Moving to Spring Boot 1.5.1 and OAuth2 + JWT token

2019-04-12 22:24发布

I'm trying to move my project to Spring Boot 1.5.1 and right now my configuration of Outh2 + JWT tokens stopped working.

Right now I receive 401 error while performing a following test:

RestTemplate restTemplate = new RestTemplate();
        CreateDecisionRequest decisionRequest = new CreateDecisionRequest(name, description, url, imageUrl, parentDecisionId, tenantId);

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        headers.add(SecurityTestUtils.AUTH_HEADER_NAME, "Bearer " + accessToken);
        HttpEntity<CreateDecisionRequest> requestEntity = new HttpEntity<CreateDecisionRequest>(decisionRequest, headers);

        ResponseEntity<DecisionResponse> responseEntity = restTemplate.exchange(String.format("http://localhost:%d/api/v1.0/decisions", port), HttpMethod.POST, requestEntity, DecisionResponse.class);

This is my RestController:

    @RestController
    @RequestMapping("/v1.0/decisions")
    public class DecisionsController {

        @Autowired
        private DecisionService decisionService;

        @PreAuthorize("hasAuthority(T(Permission).CREATE_DECISION)")
        @RequestMapping(method = RequestMethod.POST)
        public DecisionResponse createDecision(@Valid @RequestBody CreateDecisionRequest request, Authentication authentication) {
            User user = SecurityUtils.getAuthenticatedUser(authentication);
            Decision decision = decisionService.createDecision(request.getName(), request.getDescription(), request.getUrl(), request.getImageUrl(), request.getParentDecisionId(), request.getTenantId(), user.getId());
            return new DecisionResponse(decision);
        }

This is OAuth2ServerConfig:

@Configuration
public class OAuth2ServerConfig {

    public static final String RESOURCE_ID = "restservice";
    public static final String example_CLIENT_ID = "example_client_id";

    @Value("${jwt.access.token.converter.signing.key}")
    private String jwtAccessTokenConverterSigningKey;

    @Value("${jwt.access.token.validity.seconds}")
    private int accessTokenValiditySeconds;

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(tokenStore());
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setAccessTokenValiditySeconds(accessTokenValiditySeconds);
        return tokenServices;
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new TenantAwareAccessTokenConverter();

        converter.setSigningKey(jwtAccessTokenConverterSigningKey);

        DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
        DefaultUserAuthenticationConverter userTokenConverter = new DefaultUserAuthenticationConverter();
        userTokenConverter.setUserDetailsService(userDetailsService);
        accessTokenConverter.setUserTokenConverter(userTokenConverter);

        converter.setAccessTokenConverter(accessTokenConverter);

        return converter;
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

        @Autowired
        @Qualifier("authenticationManagerBean")
        private AuthenticationManager authenticationManager;

        @Value("${jwt.access.token.validity.seconds}")
        private int accessTokenValiditySeconds;

        @Autowired
        private TokenStore tokenStore;

        @Autowired
        private TokenEnhancer tokenEnhancer;

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            // @formatter:off
            endpoints
                .tokenStore(tokenStore)
                .tokenEnhancer(tokenEnhancer)
                .authenticationManager(this.authenticationManager);
            // @formatter:on
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            // @formatter:off
            clients
                .inMemory()
                    .withClient("clientapp")
                        .authorizedGrantTypes("password","refresh_token")
                        .authorities("ROLE_CLIENT")
                        .scopes("read", "write")
                        .resourceIds(RESOURCE_ID)
                        .secret("123456")
                    .and()
                    .withClient(example_CLIENT_ID)
                        .authorizedGrantTypes("implicit")
                        .scopes("read", "write")
                        .autoApprove(true)
                    .and()
                        .withClient("my-trusted-client")
                        .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                        .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                        .scopes("read", "write", "trust")
                        .accessTokenValiditySeconds(accessTokenValiditySeconds);
            // @formatter:on
        }

    }

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @Autowired
        private ResourceServerTokenServices tokenService;

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            // @formatter:off
            resources           
                .resourceId(RESOURCE_ID)
                .tokenServices(tokenService);
            // @formatter:on
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http                
                .antMatcher("/v1.0/**").authorizeRequests()
                .antMatchers("/v1.0/users/**").permitAll()
                .antMatchers("/v1.0/tenants/**").permitAll()
                .antMatchers("/v1.0/decisions/**").permitAll()
                .antMatchers("/v1.0/comments/**").permitAll()
                .antMatchers("/v1.0/commentable/**").permitAll()
                .antMatchers("/v1.0/import/**").permitAll()
                .antMatchers("/swagger**").permitAll()
                .anyRequest().authenticated()
                .and()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(STATELESS); 
            // @formatter:on
        }

    }

}

WebSecurityConfig:

@Configuration
@EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Value("${logout.success.url}")
    private String logoutSuccessUrl;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // @formatter:off
        http.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class);

        http
            .csrf().ignoringAntMatchers("/v1.0/**", "/logout")
        .and()
            .authorizeRequests()

            .antMatchers("/oauth/authorize").authenticated()
            //Anyone can access the urls
            .antMatchers("/signin/**").permitAll()
            .antMatchers("/v1.0/**").permitAll()
            .antMatchers("/auth/**").permitAll()
            .antMatchers("/actuator/health").permitAll()
            .antMatchers("/actuator/**").hasAuthority(Permission.READ_ACTUATOR_DATA)
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated()
        .and()
            .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .failureUrl("/login?error=true")
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
            .and()
                .logout()
                    .logoutUrl("/logout")
                    .logoutSuccessUrl(logoutSuccessUrl)
                    .permitAll();
        // @formatter:on
    }

    /**
     * Configures the authentication manager bean which processes authentication requests.
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}

MethodSecurityConfig:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    private DefaultMethodSecurityExpressionHandler defaultMethodExpressionHandler = new DefaultMethodSecurityExpressionHandler();

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return defaultMethodExpressionHandler;
    }

    public class DefaultMethodSecurityExpressionHandler extends org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler {

        @Override
        public StandardEvaluationContext createEvaluationContextInternal(final Authentication auth, final MethodInvocation mi) {
            StandardEvaluationContext standardEvaluationContext = super.createEvaluationContextInternal(auth, mi);
            ((StandardTypeLocator) standardEvaluationContext.getTypeLocator()).registerImport(Permission.class.getPackage().getName());
            return standardEvaluationContext;
        }
    }

}

For a some reason OAuth2AuthenticationProcessingFilter is not invoking.

In debug I can see a following filter chains:

2017-02-02 21:49:06 [main] INFO  o.s.s.web.DefaultSecurityFilterChain -
                Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/oauth/token'], Ant [pattern='/oauth/token_key'], Ant [pattern='/oauth/check_token']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@7ecb7520, org.springframework.security.web.context.SecurityContextPersistenceFilter@139dd09d, org.springframework.security.web.header.HeaderWriterFilter@4920b753, org.springframework.security.web.authentication.logout.LogoutFilter@4a3de11b, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@7be4e93a, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4ebbfb1b, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3b59e044, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3c92ea51, org.springframework.security.web.session.SessionManagementFilter@46753361, org.springframework.security.web.access.ExceptionTranslationFilter@27542320, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@64b1a881]

2017-02-02 21:49:06 [main] INFO  o.s.s.web.DefaultSecurityFilterChain -
                Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher@1, [com.decisionwanted.domain.api.filter.CorsFilter@4e672059, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@60076ce9, org.springframework.security.web.context.SecurityContextPersistenceFilter@755a147b, org.springframework.security.web.header.HeaderWriterFilter@2a86df56, org.springframework.security.web.csrf.CsrfFilter@6de4a2cd, org.springframework.security.web.authentication.logout.LogoutFilter@3e8b6e6c, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@6a85fc62, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1ee9fb22, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@209ebc6, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@424d518d, org.springframework.security.web.session.SessionManagementFilter@3de02bc0, org.springframework.security.web.access.ExceptionTranslationFilter@58d661cb, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@fe5a1ad]

2017-02-02 21:49:06 [main] INFO  o.s.s.web.DefaultSecurityFilterChain -
                Creating filter chain: Ant [pattern='/actuator/**'], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@75a8ec32, org.springframework.security.web.context.SecurityContextPersistenceFilter@25e34521, org.springframework.security.web.header.HeaderWriterFilter@2899d7a4, org.springframework.security.web.authentication.logout.LogoutFilter@5129c8c0, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@61f81842, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1bb0a050, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@7df26075, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@2cb0d5c6, org.springframework.security.web.session.SessionManagementFilter@435184b, org.springframework.security.web.access.ExceptionTranslationFilter@66cb04c1, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1a563725]

2017-02-02 21:49:06 [main] INFO  o.s.s.web.DefaultSecurityFilterChain -
                Creating filter chain: Ant [pattern='/v1.0/**'], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@378f95bc, org.springframework.security.web.context.SecurityContextPersistenceFilter@5d942ffb, org.springframework.security.web.header.HeaderWriterFilter@77699f4c, org.springframework.security.web.authentication.logout.LogoutFilter@4b16fede, org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter@2a135489, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@2d26b41b, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@160ecd0c, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@55478708, org.springframework.security.web.session.SessionManagementFilter@4ba2cce7, org.springframework.security.web.access.ExceptionTranslationFilter@46d6d280, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@16807d05]

Looks like for a some reason filter chain for pattern='/v1.0/** (where OAuth2AuthenticationProcessingFilter is present) is not invoking when I'm trying to access the following url in my test: http://localhost:%d/api/v1.0/decisions

This is a security debug output:

2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                Trying to match using Ant [pattern='/oauth/token']
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/oauth/token'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                Trying to match using Ant [pattern='/oauth/token_key']
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/oauth/token_key'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                Trying to match using Ant [pattern='/oauth/check_token']
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/oauth/check_token'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                No matches found
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                Trying to match using Ant [pattern='/oauth/token']
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/oauth/token'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                Trying to match using Ant [pattern='/oauth/token_key']
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/oauth/token_key'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                Trying to match using Ant [pattern='/oauth/check_token']
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/oauth/check_token'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                No matches found
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 1 of 13 in additional filter chain; firing Filter: 'CorsFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 2 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 3 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository -
                No HttpSession currently exists
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository -
                No SecurityContext was available from the HttpSession: null. A new one will be created.
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 4 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.h.writers.HstsHeaderWriter -
                Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@21d3e567
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 5 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.AndRequestMatcher -
                Trying to match using org.springframework.security.web.csrf.CsrfFilter$DefaultRequiresCsrfMatcher@74b80eab
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.AndRequestMatcher -
                Trying to match using NegatedRequestMatcher [requestMatcher=OrRequestMatcher [requestMatchers=[Ant [pattern='/v1.0/**'], Ant [pattern='/logout']]]]
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                Trying to match using Ant [pattern='/v1.0/**']
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/v1.0/**'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.OrRequestMatcher -
                matched
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.NegatedRequestMatcher -
                matches = false
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.matcher.AndRequestMatcher -
                Did not match
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 6 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/logout'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 7 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/login'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter -
                Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/logout'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/oauth/authorize'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/signin/**'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.u.m.AntPathRequestMatcher -
                Checking match of request : '/v1.0/decisions'; against '/v1.0/**'
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor -
                Secure object: FilterInvocation: URL: /v1.0/decisions; Attributes: [permitAll]
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor -
                Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.access.vote.AffirmativeBased -
                Voter: org.springframework.security.web.access.expression.WebExpressionVoter@3d885e49, returned: 1
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor -
                Authorization successful
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor -
                RunAsManager did not change Authentication object
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.security.web.FilterChainProxy -
                /v1.0/decisions reached end of additional filter chain; proceeding with original chain
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.a.i.a.MethodSecurityInterceptor -
                Secure object: ReflectiveMethodInvocation: public com.decisionwanted.domain.api.dto.decision.DecisionResponse com.decisionwanted.domain.api.controller.decisions.DecisionsController.createDecision(com.decisionwanted.domain.api.dto.decision.CreateDecisionRequest,org.springframework.security.core.Authentication); target is of class [com.decisionwanted.domain.api.controller.decisions.DecisionsController]; Attributes: [[authorize: 'hasAuthority(T(Permission).CREATE_DECISION)', filter: 'null', filterTarget: 'null']]
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.a.i.a.MethodSecurityInterceptor -
                Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.access.vote.AffirmativeBased -
                Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@6679d66a, returned: -1
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.access.vote.AffirmativeBased -
                Voter: org.springframework.security.access.annotation.Jsr250Voter@2ffd169b, returned: 0
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.access.vote.AffirmativeBased -
                Voter: org.springframework.security.access.vote.RoleVoter@8384b20, returned: 0
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.access.vote.AffirmativeBased -
                Voter: org.springframework.security.access.vote.AuthenticatedVoter@7a1c554f, returned: 0
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository -
                SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.a.ExceptionTranslationFilter -
                Chain processed normally
2017-02-02 22:10:59 [http-nio-auto-1-exec-2] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter -
                SecurityContextHolder now cleared, as request processing completed
2017-02-02 22:10:59 [Thread-5] INFO  o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext -
                Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@41d426b5: startup date [Thu Feb 02 22:10:19 EET 2017]; root of context hierarchy
2017-02-02 22:10:59 [Thread-5] INFO  o.s.c.s.DefaultLifecycleProcessor -
                Stopping beans in phase 2147483647

How to solve this issue?

1条回答
\"骚年 ilove
2楼-- · 2019-04-12 23:07

I found the reason of this issue:

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.5-Release-Notes

OAuth 2 Resource Filter

The default order of the OAuth2 resource filter has changed from 3 to SecurityProperties.ACCESS_OVERRIDE_ORDER - 1. This places it after the actuator endpoints but before the basic authentication filter chain. The default can be restored by setting security.oauth2.resource.filter-order = 3

So, adding the security.oauth2.resource.filter-order = 3 to application.properties did the trick! Now everything works as expected.

查看更多
登录 后发表回答