Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security Java configuration for authenticated users with a role

I am trying to configure Spring Security using Java configuration with Spring Boot.

My WebSecurityConfig class has a configure method like this

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/", "/login", "/css/**", "/js/**", "/img/**", "/bootstrap/**" ).permitAll()
            .antMatchers("/individual", "/application", "/upload").hasRole("USER")
        .and()
            .formLogin()
                .loginPage("/login")
                .successHandler(successHandler);

}

I get the login page fine for unauthenticated users, and the user authenticates. However, when trying to access the url /individual I get a 403 error and this in the log

2015-11-12 13:59:46.373 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/'
2015-11-12 13:59:46.373 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/login'
2015-11-12 13:59:46.373 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/css/**'
2015-11-12 13:59:46.373 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/js/**'
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/img/**'
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/bootstrap/**'
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/individual'; against '/individual'
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /individual; Attributes: [hasRole('ROLE_USER')]
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@4c2eda81: Principal: org.springframework.security.core.userdetails.User@4c0ab982: Username: [email protected]; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffc7f0c: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 6E0BF830C070912EAC0050D1285D5CF9; Granted Authorities: USER
2015-11-12 13:59:46.374 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6f192fd7, returned: -1
2015-11-12 13:59:46.386 DEBUG 34468 --- [nio-8090-exec-6] o.s.s.w.a.ExceptionTranslationFilter     : Access is denied (user is not anonymous); delegating to AccessDeniedHandler

if I replace .hasRole("USER") with .authenticated() it works and the user gets the page desired, but no role is being checked.

I cannot figure out how to specify that the user must be authenticated and have the role USER. I have looked at many examples and tried many combinations but I cannot get it to work as desired. Most of the examples refer to older XML based configuration as well, which I want to avoid.

What do I need to do to specify that certain URL patterns can be accessed with authenticated users with certain roles?

As requested, the success handler method looks like this

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth)
        throws IOException, ServletException {

    // Here we want to check whether the user has already started the process and redirect to the appropriate stage

    log.info("User {} has been authenticated", auth.getName());

    if(auth.getName().equals("[email protected]"))
    {
        redirectStrategy.sendRedirect(request, response, "/individual");
        return;
    }


    redirectStrategy.sendRedirect(request, response, "/application");

}

Note that this is early stage WIP, per the comments in the code. I know this works as the log message appears and without the role check in the WebSecurity class the desired page is served.

EDIT : noticed a typo in the question referring to roleService.getDefaultRole(). This was a mistake and has been corrected.

like image 556
gingerkid Avatar asked Dec 18 '22 22:12

gingerkid


1 Answers

I think your logged in user [email protected] has the wrong authorities set. In the log you can see the authorities are ['USER'], but since you are working with roles it should be ['ROLE_USER']. Where do you define the authorities for [email protected]?

Otherwise try switching

.antMatchers("/individual", "/application", "/upload").hasRole("USER")

to

.antMatchers("/individual", "/application", "/upload").hasAuthority("USER")
like image 61
FrontierPsychiatrist Avatar answered Dec 21 '22 13:12

FrontierPsychiatrist