如何使用 Spring 配置 Oauth2 授权服务器?

Posted

技术标签:

【中文标题】如何使用 Spring 配置 Oauth2 授权服务器?【英文标题】:How to configure a Oauth2 authorization server with Spring? 【发布时间】:2017-11-30 10:47:28 【问题描述】:

我正在尝试根据 Github 中的一个示例配置一个简单的Authorization Server,但我陷入了令牌验证部分。我目前的目标是提供一个保护网关的基本实现。我的理解是,如果用户会话中没有令牌允许他登录,Spring 会自动重定向到 AS。登录后,它会调用授权客户端,然后再调用另一个以将给定的代码交换为令牌。在我当前的实现中,一旦应用程序将客户端代码重定向到我的客户端登录页面,它就会从那里调用oauth/token,然后拒绝访问。我不完全了解对客户端登录页面的调用是在哪里配置的,或者它是如何进行的,然后调用oauth/token 来获取令牌。我的理解是,这是由OAuth2RestTemplate 自动完成的,而在使用@EnableOAuth2Sso 时,Spring 会自动配置一个过滤器

这是我当前的代码。

@Configuration
@ComponentScan
@EnableAutoConfiguration
@RestController
@SessionAttributes("authorizationRequest")
public class AuthserverApplication extends WebMvcConfigurerAdapter 

    public static void main(String[] args) 
        SpringApplication.run(AuthserverApplication.class, args);
    

    @Override
    public void addViewControllers(ViewControllerRegistry registry) 
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/oauth/confirm_access").setViewName("authorize");
    

    @Configuration
    @EnableResourceServer
    public static class ResourceServer extends ResourceServerConfigurerAdapter 
        @Override
        public void configure(HttpSecurity http) throws Exception 
            http
                    .antMatcher("/user")
                    .authorizeRequests().anyRequest().authenticated();
        
    

    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter 

        @Autowired
        private AuthenticationManager authenticationManager;

        @Autowired
        private UserDetailsService userService;

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception 
            clients.inMemory()
                    .withClient("acme")
                    .secret("acmesecret")
                    .authorizedGrantTypes("authorization_code", "refresh_token","password")
                    .scopes("openid")
                    .autoApprove(".*");
        

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                throws Exception 
            endpoints
                    .userDetailsService(userService)
                    .authenticationManager(authenticationManager);
        

        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer)
                throws Exception 
            oauthServer
                    .tokenKeyAccess("permitAll()")
                    .checkTokenAccess("isAuthenticated()");
        
    

    @RequestMapping("/user")
    public Map<String, String> user(Principal principal) 
        Map<String, String> map = new LinkedHashMap<>();
        map.put("name", principal.getName());
        return map;
    

    @Configuration
    @Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)
    protected static class LoginConfig extends WebSecurityConfigurerAdapter 

        @Autowired
        private AuthenticationManager authenticationManager;

        @Autowired
        private UserDetailsService userDetailsService;

        @Override
        protected void configure(HttpSecurity http) throws Exception 
            http
                    .formLogin().loginPage("/login").permitAll()
                    .and().authorizeRequests().anyRequest().authenticated()
                    .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                    .and().exceptionHandling()
                    .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));
        

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception 
            auth
                    .parentAuthenticationManager(authenticationManager)
                    .userDetailsService(userDetailsService);
        
    

使用 application.properties

server.contextPath=/uaa
security.user.password=password
security.ignored=/css/**,/js/**,/favicon.ico,/webjars/**
logging.level.org.springframework.security=DEBUG

spring.oauth2.resource.userInfoUri: http://localhost:8080/uaa/user

和客户端应用程序

@SpringBootApplication
@EnableOAuth2Sso
@RestController
public class ClientApplication extends WebSecurityConfigurerAdapter

    @RequestMapping("/user")
    public String home(Principal user) 
        return "Hello " + user.getName();
    

    public static void main(String[] args) 
        new SpringApplicationBuilder(ClientApplication.class).run(args);
    

    @Override
    public void configure(HttpSecurity http) throws Exception 
        http
                .antMatcher("/**").authorizeRequests()
                .antMatchers("/", "/login**", "/webjars/**").permitAll()
                .anyRequest()
                .authenticated();
    

使用 application.yml 文件

server:
  port: 9999
security:
  oauth2:
    client:
      clientId: acme
      clientSecret: acmesecret
      accessTokenUri: http://localhost:8080/uaa/oauth/token
      userAuthorizationUri: http://localhost:8080/uaa/oauth/authorize
      tokenName: oauth_token
      authenticationScheme: query
      clientAuthenticationScheme: form
    resource:
      userInfoUri: http://localhost:8080/uaa/user

我总是在浏览器中得到这个错误

Name .     Status      Type      Initiator .   Size       Time
login   302 x-www-form-urlencoded   Other   588 B   9 ms
authorize?client_id=acme&redirect_uri=http://localhost:9999/login&response_type=code&state=5Q67ay   302     login   380 B   66 ms
login?code=qUKZU5&state=5Q67ay  401 document    :8080/uaa/oauth/authorize?client_id=acme&redirect_uri=http://localhost:9999/login&response_type=code&state=5Q67ay   663 B   133 ms

这在服务器中

017-06-27 13:04:33.316 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-06-27 13:04:33.316 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-06-27 13:04:33.316 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-06-27 13:04:33.316 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@1c2ae5d1
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /oauth/token' doesn't match 'GET /logout
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/token'; against '/logout'
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /oauth/token' doesn't match 'PUT /logout
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /oauth/token' doesn't match 'DELETE /logout
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 5 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] 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-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-06-27 13:04:33.317 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-06-27 13:04:33.318 DEBUG 25404 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /oauth/token at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-06-27 13:04:33.318 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/token'; against '/oauth/token'
2017-06-27 13:04:33.318 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /oauth/token; Attributes: [fullyAuthenticated]
2017-06-27 13:04:33.318 DEBUG 25404 --- [nio-8080-exec-8] 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-06-27 13:04:33.318 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@5fb2cc06, returned: -1
2017-06-27 13:04:33.319 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.a.ExceptionTranslationFilter     : Access is denied (user is anonymous); redirecting to authentication entry point

org.springframework.security.access.AccessDeniedException: Access is denied
        at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) [spring-security-web-4.2.2.RELEASE.jar:4.2.2.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) [spring-boot-actuator-1.5.2.RELEASE.jar:1.5.2.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar:8.5.11]
        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]

2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.util.matcher.AndRequestMatcher   : Trying to match using Ant [pattern='/**', GET]
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /oauth/token' doesn't match 'GET /**
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.util.matcher.AndRequestMatcher   : Did not match
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.s.HttpSessionRequestCache        : Request not saved as configured RequestMatcher did not match
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.a.ExceptionTranslationFilter     : Calling Authentication entry point.
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using MediaTypeRequestMatcher 
[contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@62266a9a, matchingMediaTypes=[application/atom+xml, application/x-www-form-urlencoded, application/json, application/octet-stream, application/xml, multipart/form-data, text/xml], useEquals=false, ignoredMediaTypes=[*/*]]
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.m.MediaTypeRequestMatcher      : httpRequestMediaTypes=[application/json, application/x-www-form-urlencoded]
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.m.MediaTypeRequestMatcher      : Processing application/json
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.m.MediaTypeRequestMatcher      : application/atom+xml .isCompatibleWith application/json = false
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.m.MediaTypeRequestMatcher      : application/x-www-form-urlencoded .isCompatibleWith application/json = false
2017-06-27 13:04:33.321 DEBUG 25404 --- [nio-8080-exec-8] o.s.s.w.u.m.MediaTypeRequestMatcher      : application/json .isCompatibleWith application/json = true
2017-06-27 13:04:33.324 DEBUG 25404 --- [nio-8080-exec-8] s.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint@7a85031c
2017-06-27 13:04:33.325 DEBUG 25404 --- [nio-8080-exec-8] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed

【问题讨论】:

【参考方案1】:

我终于找到了问题。 最后是两件事的结合。我需要添加oauthServer.allowFormAuthenticationForClients() 以更改过滤器的顺序并首先允许基于用户登录信息的身份验证。然后还有另一个与客户端中的属性tokenName 相关的问题。它必须是 access_token 而不是 oauth_token 以匹配默认情况下 Spring 用于在请求中查找令牌的名称。

通过这 2 项更改,它开始起作用。

【讨论】:

以上是关于如何使用 Spring 配置 Oauth2 授权服务器?的主要内容,如果未能解决你的问题,请参考以下文章

Spring 授权服务器配置模型

Spring Security OAuth2 Demo —— 客户端模式(ClientCredentials)

如何在 Spring OAuth2 中仅通过 client_id 和 secret 进行授权?

Spring OAuth2 多服务器注解配置(资源&授权)

如何使用代码授权流在 Spring 应用程序中提取 Oauth2 访问令牌?

如何覆盖 Spring Cloud OAuth2 客户端自动配置?