spring-security force "http" authentication - java

I can't log in using spring-security.
The error is (in Mozilla)
The connection was interrupted
The connection to 127.0.0.1:8180 was interrupted while the page was loading.
The site could be temporarily unavailable or too busy. Try again in a few moments.
If you are unable to load any pages, check your computer's network connection.
If your computer or network is protected by a firewall or proxy, make sure that Firefox is permitted to access the Web.
Recently I've added a service that will get users from database. before it always was ok, but now I'm stunned. Please show me where to dig.
the url where I get this error is:
https://localhost:8180/j_spring_security_check
spring-security.xml
<http auto-config="true">
<http-basic/>
<intercept-url pattern="/sec/moderation.html" access="ROLE_MODERATOR"/>
<intercept-url pattern="/admin/*" access="ROLE_ADMIN"/>
<intercept-url pattern="/treeview" access="ROLE_ADMIN"/>
<form-login login-page="/login" default-target-url="/home" authentication-failure-url="/error"/>
<logout logout-success-url="/home"/>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="plaintext"></password-encoder>
</authentication-provider>
</authentication-manager>
CustomUserDetailsService.java
#Service
#Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserDao userDao;
#Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
UserEntity domainUser = userDao.getUser(login);
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new User(
domainUser.getLogin(),
domainUser.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(domainUser.getRole())
);
}
public Collection<? extends GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
return authList;
}
public List<String> getRoles(Integer role) {
List<String> roles = new ArrayList<String>();
if (role.intValue() == 1) {
roles.add("ROLE_MODERATOR");
roles.add("ROLE_ADMIN");
} else if (role.intValue() == 2) {
roles.add("ROLE_MODERATOR");
}
return roles;
}
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
Ia there an ability to disable https for /j_spring_security_check ?

The default login page generated by spring security does not use https, so I presume you use a custom page. The requirement for https must be in the <form action="..."> element of that page.

Related

How to refer brcypt encoder to customized authentication provider?

In my Spring project, I have defined my own custom authentication provider. Before bringing in Spring Security, I used BCrypt in Java code and now passwords are saved after BCrypting in Database.
spring-security.xml
<security:authentication-manager>
<security:authentication-provider ref="myAuthenticationProvider">
</security:authentication-provider>
</security:authentication-manager>
<b:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<b:bean id="myAuthenticationProvider" class="com.cT.www.provider.CustomAuthenticationProvider">
</b:bean>
And my custom authentication provider looks as follows.
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
public CustomAuthenticationProvider() {
super();
}
#Autowired
private PersonService personService;
#Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
System.out.println(authentication.getName() + "principal" +(String) authentication.getCredentials() );
String username = authentication.getName();
String password = (String) authentication.getCredentials();
UserSignUp user = (UserSignUp) personService.loadUserByUsername(username);
if (user == null || !user.getUsername().equalsIgnoreCase(username)) {
throw new BadCredentialsException("Username not found.");
}
if (!password.equals(user.getPassword())) {
throw new BadCredentialsException("Wrong password.");
}
List<Role> authorities = user.getAuthorities();
return new UsernamePasswordAuthenticationToken(user, password, authorities);
}
#Override
public boolean supports(Class<?> arg0) {
// TODO Auto-generated method stub
return true;
}
}
I don't wanna use user-service-ref in spring-security.xml wihtin authentication-manager.
If your user passwords are already saved as BCrypt in database you don't need much of thing to do. In your authenticate method just replace your password checking condition with below
if (BCrypt.checkpw(password, user.getPassword())) {
throw new BadCredentialsException("Wrong password.");
}
Refer BCrypt source for more details.
You can refer to BCryptPasswordEncoder this way:
<authentication-manager>
<authentication-provider>
<password-encoder ref="encoder" />
</authentication-provider>
</authentication-manager>
<beans:bean id="encoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<beans:constructor-arg name="strength" value="11" />
</beans:bean>
For details see http://www.mkyong.com/spring-security/spring-security-password-hashing-example/

Spring security added prefix "ROLE_" to all roles name?

I have this code in my Web Security Config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**")
.hasRole("ADMIN")
.and()
.httpBasic().and().csrf().disable();
}
So I added an user with "ADMIN" role in my database and I always get 403 error when I tryed loggin with this user, then I enabled log for spring and I found this line:
2015-10-18 23:13:24.112 DEBUG 4899 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/user/login; Attributes: [hasRole('ROLE_ADMIN')]
Why Spring Security is looking for "ROLE_ADMIN" instead "ADMIN"?
Spring security adds the prefix "ROLE_" by default.
If you want this removed or changed, take a look at
How to change role from interceptor-url?
EDIT: found this as well:
Spring Security remove RoleVoter prefix
In Spring 4, there are two methods hasAuthority() and hasAnyAuthority() defined in org.springframework.security.access.expression.SecurityExpressionRoot class. These two methods checks only your custom role name without adding ROLE_ prefix. Definition as follows:
public final boolean hasAuthority(String authority) {
return hasAnyAuthority(authority);
}
public final boolean hasAnyAuthority(String... authorities) {
return hasAnyAuthorityName(null, authorities);
}
private boolean hasAnyAuthorityName(String prefix, String... roles) {
Set<String> roleSet = getAuthoritySet();
for (String role : roles) {
String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
if (roleSet.contains(defaultedRole)) {
return true;
}
}
return false;
}
private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) {
if (role == null) {
return role;
}
if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) {
return role;
}
if (role.startsWith(defaultRolePrefix)) {
return role;
}
return defaultRolePrefix + role;
}
Example usage:
<http auto-config="false" use-expressions="true" pattern="/user/**"
entry-point-ref="loginUrlAuthenticationEntryPoint">
<!--If we use hasAnyAuthority, we can remove ROLE_ prefix-->
<intercept-url pattern="/user/home/yoneticiler" access="hasAnyAuthority('FULL_ADMIN','ADMIN')"/>
<intercept-url pattern="/user/home/addUser" access="hasAnyAuthority('FULL_ADMIN','ADMIN')"/>
<intercept-url pattern="/user/home/addUserGroup" access="hasAuthority('FULL_ADMIN')"/>
<intercept-url pattern="/user/home/deleteUserGroup" access="hasAuthority('FULL_ADMIN')"/>
<intercept-url pattern="/user/home/**" access="hasAnyAuthority('FULL_ADMIN','ADMIN','EDITOR','NORMAL')"/>
<access-denied-handler error-page="/403"/>
<custom-filter position="FORM_LOGIN_FILTER" ref="customUsernamePasswordAuthenticationFilter"/>
<logout logout-url="/user/logout"
invalidate-session="true"
logout-success-url="/user/index?logout"/>
<!-- enable csrf protection -->
<csrf/>
</http> <beans:bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:constructor-arg value="/user"/>
</beans:bean>
As #olyanren said, you can use hasAuthority() method in Spring 4 instead of hasRole(). I am adding JavaConfig example:
#Override
protected void configure(HttpSecurity http) throws Exception {
.authorizeRequests()
.antMatchers("/api/**")
.access("hasAuthority('ADMIN')")
.and()
.httpBasic().and().csrf().disable();
}
You can create a mapper to add ROLE_ at the beginning of all of your roles:
#Bean
public GrantedAuthoritiesMapper authoritiesMapper() {
SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
mapper.setPrefix("ROLE_"); // this line is not required
mapper.setConvertToUpperCase(true); // convert your roles to uppercase
mapper.setDefaultAuthority("USER"); // set a default role
return mapper;
}
The you should add the mapper to your provider:
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
// your config ...
provider.setAuthoritiesMapper(authoritiesMapper());
return provider;
}
_ROLE prefix is used by spring security, to identify that it is as a role. A role has a set of privileges a.k.a Authorities, these authorities define varies permissions for a role.
ex:- EDIT_PROFILE, DELETE_PROFILE
You can define both the roles and authorities, if you are defining a role then it must be prefixed with "ROLE_"
In your case you are looking for a role, so by default spring security looks for a string that is prefixed with "ROLE_".

Multiple login with spring security + web services

I am working with spring-security 3.1 to implement two different logons. The first thing I have to a database that brings me CustomUserDetailService credentials datos.Este the same database is for administrator access. The second port is for the user but the information comes from a web service I call him with me a method validates the user. The problem I have with the second port, and to develop a CustomAuthenticationProvider for the second AuthenticationManager (web service), but when I try to access the spring-security user sends me to error page login.html? Error = true the furmulario administrator access. Esteb is my configuration file:
<http pattern="../resources/**" security="none" />
<http pattern="/login.html*" security="none" />
<http pattern="/loginUser.html*" security="none" />
<!-- USER -->
<http auto-config="true" authentication-manager-ref="wsAuthenticationManager" use-expressions="true" pattern="/testUser/**">
<intercept-url pattern="/loginUser.html" access="permitAll" />
<intercept-url pattern="/testUser/**" access="hasRole('user')" />
<access-denied-handler error-page="/403" />
<form-login login-page="/loginUser.html"
authentication-failure-url="/loginUser.html?login_error=true"
default-target-url="/testUser" />
<logout invalidate-session="true" logout-success-url="/logintUser.html" />
</http>
<beans:bean id="customAuthenticationProvider" class="net.universia.test.service.CustomAuthenticationProvider" />
<!-- Acceso contra WS -->
<authentication-manager id="wsAuthenticationManager">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
<!--ADMIN -->
<http auto-config="true" use-expressions="true" authentication-manager-ref="authenticationManager" >
<intercept-url pattern="/login.html" access="permitAll" />
<intercept-url pattern="/test/**" access="hasRole('admin')" />
<intercept-url pattern="/member/**" access="hasAnyRole('moderator','admin')" />
<intercept-url pattern="/testUser/**" access="hasRole('admin')" />
<access-denied-handler error-page="/403" />
<form-login login-page="/login.html"
authentication-failure-url="/login.html?login_error=true"
username-parameter="j_username" password-parameter="j_password"/>
<logout invalidate-session="true" logout-success-url="/loginUser.html" />
<remember-me user-service-ref="customUserDetailsService" />
</http>
<beans:bean id="customUserDetailsService" class="net.universia.test.service.CustomUserDetailsService" />
<beans:bean id="md5PasswordEncoder"
class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
<!-- Acceso contra base de datos -->
<authentication-manager alias="authenticationManager" id="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService">
<password-encoder hash="md5" />
</authentication-provider>
</authentication-manager>
</beans:beans>
CustomUserDetailService para administrator:
#Service
#Transactional(readOnly=true)
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private HibernateTestAdminDaoImpl userDAO;
public UserDetails loadUserByUsername(String login)throws UsernameNotFoundException {
TestAdmin userAdmin = null;
try {
userAdmin = userDAO.getTestAdmin(login);
} catch (BussinessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
return new User(
userAdmin.getLoginAdmin(),
userAdmin.getPasswordAdmin(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities(userAdmin.getRole().getIdRole())
);
}
public Collection<? extends GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
return authList;
}
public List<String> getRoles(Integer role) {
List<String> roles = new ArrayList<String>();
if (role.intValue() == 1) {
roles.add("admin");
roles.add("moderator");
} else if (role.intValue() == 2) {
roles.add("moderator");
}
return roles;
}
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
CustomAuthenticationProvider user:
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Autowired
private HibernateTestUsuarioDaoImpl userDAO;
UniversiaUser usw;
public CustomAuthenticationProvider() {
super();
}
// Retorna credenciales del usuario web service
public Authentication authenticate(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
/*
final String loginUser = authentication.getName();
final String password = authentication.getCredentials().toString();
try {
usw = userDAO.loginUserWS(loginUser, password);
} catch (UserRegistryWSException e) {
String errorCode = e.getLocalizedMessage();
System.out.print(errorCode);
} catch (Exception e) {
UsuarioUniversiaException ee = new UsuarioUniversiaException(
UsuarioUniversiaException.FERIA_VIRTUAL_USER_ERROR_LOGIN,
e);
ee.setLogin(loginUser);
throw ee;
}
if (usw.getEmail().equals("loginUser")) {
final List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("user"));
final UserDetails principal = new User(loginUser, password, grantedAuths);
final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);
return auth;
} else {
return null;
}
*/
//Test parameters
final String loginUser = request.getParameter("username");
final String password = request.getParameter("password");
if (loginUser.equals("admin") && password.equals("system")) {
final List<GrantedAuthority> grantedAuths = new ArrayList<>();
grantedAuths.add(new SimpleGrantedAuthority("user"));
final UserDetails principal = new User(loginUser, password, grantedAuths);
final Authentication auth = new UsernamePasswordAuthenticationToken(principal, password, grantedAuths);
return auth;
} else {
return null;
}
}
#Override
public boolean supports(final Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
#Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
// TODO Auto-generated method stub
return null;
}
}
In customautheticationprovider discuss what comes from the webservice and send test parameters
Thanks and any help is welcome
Now I have two running !!!
One customAuthenticationProvider user and customAuthenticationDetailService for Administrator and implement each filter

How to redirect to the homepage if the user accesses the login page after being logged in?

Here is my spring security config:
<http pattern="/auth/login" security="none" />
<http pattern="/auth/loginFailed" security="none" />
<http pattern="/resources/**" security="none" />
<http auto-config="true" access-decision-manager-ref="accessDecisionManager">
<intercept-url pattern="/auth/logout" access="permitAll"/>
<intercept-url pattern="/admin/**" access="ADMINISTRATIVE_ACCESS"/>
<intercept-url pattern="/**" access="XYZ_ACCESS"/>
<form-login
login-page="/auth/login"
authentication-failure-url="/auth/loginFailed"
authentication-success-handler-ref="authenticationSuccessHandler" />
<logout logout-url="/auth/logout" logout-success-url="/auth/login" />
</http>
The authenticationSuccessHandler extends the SavedRequestAwareAuthenticationSuccessHandler ensuring that the user is redirected to the page he originally requested.
However, since /auth/login is marked as security="none", I am unable to successfully redirect the user to the homepage if he accesses the login page after being logged in. I believe this is the right user experience too.
I tried the below too but the Principal object is always null, presumably because of the security="none" attribute again.
#RequestMapping(value = "/auth/login", method = GET)
public String showLoginForm(HttpServletRequest request, Principal principal) {
if(principal != null) {
return "redirect:/";
}
return "login";
}
I've checked the topic more deeply than last time and found that you have to determine if user is authenticated by yourself in controller. Row Winch (Spring Security dev) says here:
Spring Security is not aware of the internals of your application
(i.e. if you want to make your login page flex based upon if the user
is logged in or not). To show your home page when the login page is
requested and the user is logged in use the SecurityContextHolder in
the login page (or its controller) and redirect or forward the user to
the home page.
So solution would be determining if user requesting /auth/login is anonymous or not, something like below.
applicationContext-security.xml:
<http auto-config="true" use-expressions="true"
access-decision-manager-ref="accessDecisionManager">
<intercept-url pattern="/auth/login" access="permitAll" />
<intercept-url pattern="/auth/logout" access="permitAll" />
<intercept-url pattern="/admin/**" access="ADMINISTRATIVE_ACCESS" />
<intercept-url pattern="/**" access="XYZ_ACCESS" />
<form-login login-page="/auth/login"
authentication-failure-url="/auth/loginFailed"
authentication-success-handler-ref="authenticationSuccessHandler" />
<logout logout-url="/auth/logout" logout-success-url="/auth/login" />
</http>
<beans:bean id="defaultTargetUrl" class="java.lang.String">
<beans:constructor-arg value="/content" />
</beans:bean>
<beans:bean id="authenticationTrustResolver"
class="org.springframework.security.authentication.AuthenticationTrustResolverImpl" />
<beans:bean id="authenticationSuccessHandler"
class="com.example.spring.security.MyAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" ref="defaultTargetUrl" />
</beans:bean>
Add to applicationContext.xml bean definition:
<bean id="securityContextAccessor"
class="com.example.spring.security.SecurityContextAccessorImpl" />
which is class
public final class SecurityContextAccessorImpl
implements SecurityContextAccessor {
#Autowired
private AuthenticationTrustResolver authenticationTrustResolver;
#Override
public boolean isCurrentAuthenticationAnonymous() {
final Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
return authenticationTrustResolver.isAnonymous(authentication);
}
}
implementing simple interface
public interface SecurityContextAccessor {
boolean isCurrentAuthenticationAnonymous();
}
(SecurityContextHolder accessing code is decoupled from controller, I followed suggestion from this answer, hence SecurityContextAccessor interface.)
And last but not least redirect logic in controller:
#Controller
#RequestMapping("/auth")
public class AuthController {
#Autowired
SecurityContextAccessor securityContextAccessor;
#Autowired
#Qualifier("defaultTargetUrl")
private String defaultTargetUrl;
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login() {
if (securityContextAccessor.isCurrentAuthenticationAnonymous()) {
return "login";
} else {
return "redirect:" + defaultTargetUrl;
}
}
}
Defining defaultTargetUrl String bean seems like a hack, but I don't have better way not to hardcode url... (Actually in our project we use <util:constant> with class containing static final String fields.) But it works after all.
You could also restrict your login page to ROLE_ANONYMOUS and set an <access-denied-handler />:
<access-denied-handler ref="accessDeniedHandler" />
<intercept-url pattern="/auth/login" access="ROLE_ANONYMOUS" />
And in your handler check if the user is already authenticated:
#Service
public class AccessDeniedHandler extends AccessDeniedHandlerImpl {
private final String HOME_PAGE = "/index.html";
#Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && !(auth instanceof AnonymousAuthenticationToken)) {
response.sendRedirect(HOME_PAGE);
}
super.handle(request, response, e);
}
}
Implement a Redirect Interceptor for this purpose:
The Interceptor (implementing HandlerInterceptor interface) check if someone try to access the login page, and if this person is already logged in, then the interceptor sends a redirect to the index page.
public class LoginPageRedirectInterceptor extends HandlerInterceptorAdapter {
private String[] loginPagePrefixes = new String[] { "/login" };
private String redirectUrl = "/index.html";
private UrlPathHelper urlPathHelper = new UrlPathHelper();
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
if (isInLoginPaths(this.urlPathHelper.getLookupPathForRequest(request))
&& isAuthenticated()) {
response.setContentType("text/plain");
sendRedirect(request, response);
return false;
} else {
return true;
}
}
private boolean isAuthenticated() {
Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
return false;
}
if (authentication instanceof AnonymousAuthenticationToken) {
return false;
}
return authentication.isAuthenticated();
}
private void sendRedirect(HttpServletRequest request,
HttpServletResponse response) {
String encodedRedirectURL = response.encodeRedirectURL(
request.getContextPath() + this.redirectUrl);
response.setStatus(HttpStatus.SC_TEMPORARY_REDIRECT);
response.setHeader("Location", encodedRedirectURL);
}
private boolean isInLoginPaths(final String requestUrl) {
for (String login : this.loginPagePrefixes) {
if (requestUrl.startsWith(login)) {
return true;
}
}
return false;
}
}
You can keep it simple flow by access-denied-page attribute in http element or as dtrunk said to write handler for access denied as well as. the config would be like
<http access-denied-page="/403" ... >
<intercept-url pattern="/login" access="ROLE_ANONYMOUS" />
<intercept-url pattern="/user/**" access="ROLE_USER" />
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/login" default-target-url="/home" ... />
...
</http>
in controller for /403
#RequestMapping(value = "/403", method = RequestMethod.GET)
public String accessDenied() { //simple impl
return "redirect:/home";
}
and for /home
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String home(Authentication authentication) {
// map as many home urls with Role
Map<String, String> dashBoardUrls = new HashMap<String, String>();
dashBoardUrls.put("ROLE_USER", "/user/dashboard");
dashBoardUrls.put("ROLE_ADMIN", "/admin/dashboard");
String url = null;
Collection<? extends GrantedAuthority> grants = authentication
.getAuthorities();
// for one role per user
for (GrantedAuthority grantedAuthority : grants) {
url = dashBoardUrls.get(grantedAuthority.getAuthority());
}
if (url == null)
return "/errors/default_access_denied.jsp";
return "redirect:" + url;
}
and when you make request for /admin/dashboard without logged in, it will redirect /login automatically by security
<http pattern="/login" auto-config="true" disable-url-rewriting="true">
<intercept-url pattern="/login" access="ROLE_ANONYMOUS"/>
<access-denied-handler error-page="/index.jsp"/>
</http>
You can try checking
if(SecurityContextHolder.getContext().getAuthentication() == null)
True means the user isn't authenticated, and thus can be sent to the login page. I don't know how robust/reliable this is, but it seems reasonable to try.

Spring Security returning guest instead of UserDetails for Authentication.getPrincipal()

I'm trying to implement spring security 3.1.0.M1 and I'm unable to get my application to set the Authentication.getPrincipal to my custom UserDetails implementation. It always returns a principal of "guest" when I try to get the logged in user. See getLoggedInUser method below.
In Users.java (UserDetails impl) the getAuthorities method never gets called and maybe that's why the user_role doesn't get assigned.
to Maybe I've misconfigured something...I've attached an outline of my implementation hoping someone can spot my error. Thanks for the assistance!
public static Users getLoggedInUser() {
Users user = null;
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.isAuthenticated()) {
Object principal = auth.getPrincipal();
if (principal instanceof Users) {
user = (Users) principal;
}
}
return user;
}
security context file(removed the xml and schema definitions):
<global-method-security secured-annotations="enabled">
</global-method-security>
<http security="none" pattern="/services/rest-api/1.0/**" />
<http security="none" pattern="/preregistered/**" />
<http access-denied-page="/auth/denied.html">
<intercept-url
pattern="/**/*.xhtml"
access="ROLE_NONE_GETS_ACCESS" />
<intercept-url
pattern="/auth/**"
access="ROLE_ANONYMOUS,ROLE_USER" />
<intercept-url
pattern="/auth/*"
access="ROLE_ANONYMOUS" />
<intercept-url
pattern="/**"
access="ROLE_USER" />
<form-login
login-processing-url="/j_spring_security_check.html"
login-page="/auth/login.html"
default-target-url="/registered/home.html"
authentication-failure-url="/auth/login.html?_dc=45" />
<logout logout-url="/auth/logout.html"
logout-success-url="/" />
<anonymous username="guest" granted-authority="ROLE_ANONYMOUS"/>
<remember-me user-service-ref="userManager" key="valid key here"/>
</http>
<!-- Configure the authentication provider -->
<authentication-manager>
<authentication-provider user-service-ref="userManager">
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
UserDetails Implementation (Users.java):
public class Users implements Serializable, UserDetails {
public Collection<GrantedAuthority> getAuthorities() {
List<GrantedAuthority> auth = new ArrayList<GrantedAuthority>();
auth.add(new GrantedAuthorityImpl("ROLE_USER"));
return auth;
}
}
user-service-ref="userManager" (UserManagerImpl.java):
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
Users user = null;
try {
user = userDAO.findByUsername(username);
} catch (DataAccessException ex) {
throw new UsernameNotFoundException("Invalid login", ex);
}
if (user == null) {
throw new UsernameNotFoundException("User not found.");
}
return user;
}
Are you not getting compilation error on this line: auth.add("ROLE_USER");?
I think it should be : auth.add(new SimpleGrantedAuthority("ROLE_USER"));

Categories

Resources