I´m developing an application with spring security authentication and MongoDB. The authentication method is working fine but only with ROLE_ADMIN
. All methods that I need authentication for are annotated with:
@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
When I try to authenticate with a user that has ROLE_USER
I always get access declined error.
My spring security config is:
<security:global-method-security pre-post-annotations="enabled" />
<security:http auto-config="true" use-expressions="true">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<intercept-url pattern="/admin/**"
access="hasRole('ROLE_ADMIN') and hasRole('ROLE_USER')" />
<security:form-login login-page="/login" default-target-url="/admin/main"
authentication-failure-url="/accessdenied" />
<security:logout logout-success-url="/logout" />
<security:session-management>
<security:concurrency-control error-if-maximum-exceeded="true"
max-sessions="1"/>
</security:session-management>
</security:http>
If I use:
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN') and hasRole('ROLE_USER')" />
I get access denied for both ROLE_ADMIN
and ROLE_USER
.
If I use:
<intercept-url pattern="/admin/**" access="hasAnyRole('ROLE_ADMIN', 'ROLE_USER')" />
I can log in with a ROLE_ADMIN
user but I can´t with ROLE_USER
.
and in my LoginService
I have:
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException {
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
User user = getUserDetail(email);
userdetails = new org.springframework.security.core.userdetails.User(
user.getEmail(), user.getPwd(), enabled,
accountNonExpired, credentialsNonExpired, accountNonLocked,
getAuthorities(user.getIsAdmin()));
return userdetails;
}
public List<GrantedAuthority> getAuthorities(Integer role) {
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
if (role.intValue() == 0) {
authList.add(new SimpleGrantedAuthority("ROLE_USER"));
} else if (role.intValue() == 1) {
authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
System.out.println(authList);
return authList;
}
What am I missing?
hasRole, hasAnyRole. These expressions are responsible for defining the access control or authorization to specific URLs and methods in our application: @Override protected void configure(final HttpSecurity http) throws Exception { ... . antMatchers("/auth/admin/*").
By default, Spring Security uses a thread-local copy of this class. This means each request in our application has its security context that contains details of the user making the request. To use it, we simply call the static methods in SecurityContextHolder: Authentication auth = SecurityContextHolder.
antMatchers() is then used to apply authorization to one or more paths you specify in antMatchers() . Such as permitAll() or hasRole('USER3') . These only get applied if the first http. antMatcher() is matched.
User, Role and Privilege The User. The Role represents the high-level roles of the user in the system. Each role will have a set of low-level privileges. The Privilege represents a low-level, granular privilege/authority in the system.
When you have this kind of problem, please try first adding many System.out.println
(or debug log) to see if your method is working, also change:
hasRole('ROLE_ADMIN') and hasRole('ROLE_USER')
for
hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')
And check if the role.intValue() == 0
prints true
with a sysout
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With