0

I am trying to implement role based authorization using Spring security 6 and Google for authentication. Though the solution works for endpoint (/authnz/user) configured for any authorized user but fails for the endpoint (/authnz/super/payments)in which the user should have a given role ( e.g ROLE='SUPER'). For the testing purpose I have created a UserDetailsService where the system always return the user who has the ROLE=SUPER

I tried the answer provided here https://stackoverflow.com/a/72392539/584154 but it didn't work for me.

Below is my configuration class

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http, UserDetailsService userDetailsService) throws Exception {
        http.authorizeHttpRequests((authorizeHttpRequests) ->
                authorizeHttpRequests
                    .requestMatchers("/authnz/super/**").hasRole("SUPER")
                    .requestMatchers("/authnz/**").authenticated()
                    .anyRequest().permitAll() )
            .csrf(c -> c.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) )
            .exceptionHandling((e) ->e.accessDeniedPage("/failure") )
            .logout(l -> l.logoutSuccessUrl("/")
                    .permitAll()
                    .deleteCookies("JSESSIONID")
                    .invalidateHttpSession(true) )
            .oauth2Login()
            .userInfoEndpoint()
            ;
         DefaultSecurityFilterChain build = http.build();
         return build;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetailsService svc = new MyUserDetailsService();
        return svc;
    }
    private static class MyUserDetailsService implements UserDetailsService{
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            System.out.println("load by username");
            UserDetails userDetails = User.builder().roles("SUPER").build();
            return userDetails;
        }
    }

The exception I am stuck at is AccessDeniedException: Access Denied with following snippet of trace:

2023-04-18T00:13:43.661-04:00 TRACE 8488 --- [nio-8080-exec-1] estMatcherDelegatingAuthorizationManager : Authorizing SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@4396eea6]
2023-04-18T00:13:43.662-04:00 TRACE 8488 --- [nio-8080-exec-1] estMatcherDelegatingAuthorizationManager : Checking authorization on SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@4396eea6] using AuthorityAuthorizationManager[authorities=[ROLE_SUPER]]
2023-04-18T00:13:43.662-04:00 TRACE 8488 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=Name: [1232323232], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_blah=jasdfkjadfkjadfda, sub=1232323232, email_verified=true, iss=https://accounts.google.com, given_name=nash, locale=en, nonce=ahajkfsioweurwpifaspoiofasaippo, picture=https://lh3.googleusercontent.com/a/euywuiyruiqyuiryqruiqy, aud=[blahblah.apps.googleusercontent.com], azp=blahblah.apps.googleusercontent.com, name=yada, exp=2023-04-18T05:13:29Z, family_name=blah, iat=2023-04-18T04:13:29Z, email=blash@gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=hafdspowepo], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]] from SPRING_SECURITY_CONTEXT
2023-04-18T00:13:43.662-04:00 TRACE 8488 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Did not set SecurityContextHolder since already authenticated OAuth2AuthenticationToken [Principal=Name: [1232323232], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_blah=jasdfkjadfkjadfda, sub=1232323232, email_verified=true, iss=https://accounts.google.com, given_name=nash, locale=en, nonce=ahajkfsioweurwpifaspoiofasaippo, picture=https://lh3.googleusercontent.com/a/euywuiyruiqyuiryqruiqy, aud=[blahblah.apps.googleusercontent.com], azp=blahblah.apps.googleusercontent.com, name=yada, exp=2023-04-18T05:13:29Z, family_name=blah, iat=2023-04-18T04:13:29Z, email=blash@gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=hafdspowepo], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]
2023-04-18T00:13:43.662-04:00 TRACE 8488 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter     : Sending OAuth2AuthenticationToken [Principal=Name: [1232323232], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_blah=jasdfkjadfkjadfda, sub=1232323232, email_verified=true, iss=https://accounts.google.com, given_name=nash, locale=en, nonce=ahajkfsioweurwpifaspoiofasaippo, picture=https://lh3.googleusercontent.com/a/euywuiyruiqyuiryqruiqy, aud=[blahblah.apps.googleusercontent.com], azp=blahblah.apps.googleusercontent.com, name=yada, exp=2023-04-18T05:13:29Z, family_name=blah, iat=2023-04-18T04:13:29Z, email=blash@gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=hafdspowepo], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]] to access denied handler since access is denied

org.springframework.security.access.AccessDeniedException: Access Denied
    at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilter(AuthorizationFilter.java:98) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-6.0.2.jar:6.0.2]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.2.jar:6.0.2]

I have also checked in my code , at github if you want to give it a shot. Just edit the client-id and client-secret in the application.yml file

dur
  • 15,689
  • 25
  • 79
  • 125
Geek
  • 627
  • 1
  • 8
  • 18

0 Answers0