Spring OAuth2 隐式流程 - 身份验证服务器不处理 POST /oauth/authorize 请求
Posted
技术标签:
【中文标题】Spring OAuth2 隐式流程 - 身份验证服务器不处理 POST /oauth/authorize 请求【英文标题】:Spring OAuth2 Implicit Flow - Auth server not processing the POST /oauth/authorize request 【发布时间】:2017-08-08 23:35:58 【问题描述】:我有一个授权服务器 (http://localhost:8082)、资源服务器和隐式客户端 (http://localhost:8080) 项目。问题是当客户端请求授权(令牌)时,身份验证服务器显示登录屏幕,但在成功登录后它重定向到 GET http://localhost:8082/ 而不是 http://localhost:8082/authorize?client_id=...(根据客户端的要求)
我看到了这个日志:
隐式客户端:
.s.o.c.t.g.i.ImplicitAccessTokenProvider : Retrieving token from http://localhost:8082/oauth/authorize
o.s.web.client.RestTemplate : Created POST request for "http://localhost:8082/oauth/authorize"
.s.o.c.t.g.i.ImplicitAccessTokenProvider : Encoding and sending form: response_type=[token], client_id=[themostuntrustedclientid], scope=[read_users write_users], redirect_uri=[http://localhost:8080/api/accessTokenExtractor]
o.s.web.client.RestTemplate : POST request for "http://localhost:8082/oauth/authorize" resulted in 302 (null)
o.s.s.web.DefaultRedirectStrategy : Redirecting to 'http://localhost:8082/login?client_id=themostuntrustedclientid&response_type=token&redirect_uri=http://localhost:8080/api/accessTokenExtractor'
认证服务器:
o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /oauth/authorize' doesn't match 'GET /**
o.s.s.w.util.matcher.AndRequestMatcher : Did not match
o.s.s.w.s.HttpSessionRequestCache : Request not saved as configured RequestMatcher did not match
o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point.
o.s.s.web.DefaultRedirectStrategy : Redirecting to 'http://localhost:8082/login'
隐式客户端正在为 /oauth/authorize 进行 POST,而不是 GET,并且 authserver 不存储 POST 请求。认证服务器返回一个重定向 302,隐式客户端将浏览器重定向到这个 url:http://localhost:8082/login?client_id=themostuntrustedclientid&response_type=token&redirect_uri=http://localhost:8080/api/accessTokenExtractor
成功登录后,auth 服务器没有目标 url,所以它显示http://localhost:8082/,所以它不处理任何 /oauth/authorize 请求...问题出在哪里?
授权服务器配置:
@Configuration
class OAuth2Config extends AuthorizationServerConfigurerAdapter
@Autowired
private AuthenticationManager authenticationManager
@Bean
public TokenStore tokenStore()
return new InMemoryTokenStore();
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception
clients.inMemory()
.withClient("themostuntrustedclientid")
.secret("themostuntrustedclientsecret")
.authorizedGrantTypes("implicit")
.authorities("ROLE_USER")
.scopes("read_users", "write_users")
.accessTokenValiditySeconds(60)
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
endpoints.authenticationManager(this.authenticationManager);
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception
//security.checkTokenAccess('hasRole("ROLE_RESOURCE_PROVIDER")')
security.checkTokenAccess('isAuthenticated()')
@Configuration
@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception
auth.inMemoryAuthentication().withUser("jose").password("mypassword").roles('USER').and()
.withUser("themostuntrustedclientid").password("themostuntrustedclientsecret").roles('USER')
@Override
protected void configure(HttpSecurity http) throws Exception
http
.csrf()
//
//XXX Si se usa implicit descomentar
.ignoringAntMatchers("/oauth/authorize")
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
//.httpBasic()
.formLogin()
.loginPage("/login").permitAll()
隐式客户端配置:
@Configuration
class OAuth2Config
@Value('$oauth.authorize:http://localhost:8082/oauth/authorize')
private String authorizeUrl
@Value('$oauth.token:http://localhost:8082/oauth/token')
private String tokenUrl
@Autowired
private OAuth2ClientContext oauth2Context
@Bean
OAuth2ProtectedResourceDetails resource()
ImplicitResourceDetails resource = new ImplicitResourceDetails()
resource.setAuthenticationScheme(AuthenticationScheme.header)
resource.setAccessTokenUri(authorizeUrl)
resource.setUserAuthorizationUri(authorizeUrl);
resource.setClientId("themostuntrustedclientid")
resource.setClientSecret("themostuntrustedclientsecret")
resource.setScope(['read_users', 'write_users'])
resource
@Bean
OAuth2RestTemplate restTemplate()
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resource(), oauth2Context)
//restTemplate.setAuthenticator(new ApiConnectOAuth2RequestAuthenticator())
restTemplate
@Configuration
class SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception
auth.eraseCredentials(false)
.inMemoryAuthentication().withUser("jose").password("mypassword").roles('USER')
@Override
protected void configure(HttpSecurity http) throws Exception
http
.csrf()
.ignoringAntMatchers("/accessTokenExtractor")
.and()
.authorizeRequests()
.anyRequest().hasRole('USER')
.and()
.formLogin()
.loginPage("/login").permitAll()
【问题讨论】:
【参考方案1】:问题出在 Auth 服务器的 SecurityConfig 中。隐式客户端自动发送带有 client_id 和 client_secret 的基本授权标头。我的身份验证服务器配置为使用表单登录而不是基本身份验证。我改变了它,现在它可以按预期工作了:
@Override
protected void configure(HttpSecurity http) throws Exception
http
.csrf()
//
//XXX Si se usa implicit descomentar
.ignoringAntMatchers("/oauth/authorize")
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
【讨论】:
以上是关于Spring OAuth2 隐式流程 - 身份验证服务器不处理 POST /oauth/authorize 请求的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Security 实现 OAuth2 隐式授权
具有基本身份验证和自定义 UserDetailsService 的 Spring Boot OAuth2
Spring oauth2令牌请求中未实际使用的基本身份验证过滤器和身份验证入口点
Spring Security OAuth2 AngularJS |注销流程
OAuth2“社交登录”流程(允许通过 Facebook/Twitter 进行 OAuth2 身份验证):是不是有任何示例/文献?