我正在使用Spring授权服务器0.3.1并从OAuth客户端调用**/oauth2/revoke**端点(angular-oauth2-oidc)。负载:
client_id: my-client-id
token: eyJraWQiOiJlYzA3N2Y2OC1jMjQ1LTQ[the rest is stripped for readability]
token_type_hint: access_token
响应包含错误“invalid_client”。
经过几分钟的调试后,发现在org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenRevocationAuthenticationProvider#authenticate方法中抛出了异常:
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OAuth2TokenRevocationAuthenticationToken tokenRevocationAuthentication =
(OAuth2TokenRevocationAuthenticationToken) authentication;
OAuth2ClientAuthenticationToken clientPrincipal =
getAuthenticatedClientElseThrowInvalidClient(tokenRevocationAuthentication);
获取已验证的客户端或抛出无效的客户端方法:
static OAuth2ClientAuthenticationToken getAuthenticatedClientElseThrowInvalidClient(Authentication authentication) {
OAuth2ClientAuthenticationToken clientPrincipal = null;
if (OAuth2ClientAuthenticationToken.class.isAssignableFrom(authentication.getPrincipal().getClass())) {
clientPrincipal = (OAuth2ClientAuthenticationToken) authentication.getPrincipal();
}
if (clientPrincipal != null && clientPrincipal.isAuthenticated()) {
return clientPrincipal;
}
throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_CLIENT);
}
看起来OAuth2 TokenRevocationAuthenticationProvider期望传递的authentication对象在主体中具有OAuth2 ClientAuthenticationToken,但实际上主体是JwtAuthenticationToken的示例。据我所知,由于调用具有不记名令牌,因此它被授权,并且JwtAuthenticationToken被设置为SecurityContextHolder:
2022-06-28 23:27:01.392 DEBUG 16904 --- [ XNIO-1 task-1] o.s.security.web.FilterChainProxy : Securing POST /oauth2/revoke
2022-06-28 23:27:01.393 DEBUG 16904 --- [ XNIO-1 task-1] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-06-28 23:27:01.394 DEBUG 16904 --- [ XNIO-1 task-1] o.s.s.o.s.r.a.JwtAuthenticationProvider : Authenticated token
2022-06-28 23:27:01.397 DEBUG 16904 --- [ XNIO-1 task-1] .o.s.r.w.BearerTokenAuthenticationFilter : Set SecurityContextHolder to JwtAuthenticationToken [Principal=org.springframework.security.oauth2.jwt.Jwt@1615fb2d, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=null], Granted Authorities=[SCOPE_openid, SCOPE_profile, SCOPE_offline_access, SCOPE_email]]
2022-06-28 23:27:01.398 DEBUG 16904 --- [ XNIO-1 task-1] o.s.s.w.a.i.FilterSecurityInterceptor : Authorized filter invocation [POST /oauth2/revoke] with attributes [authenticated]
我是否遗漏了什么?如何在此处获得OAuth2 ClientAuthenticationToken而不是JwtAuthenticationToken?
1条答案
按热度按时间lnxxn5zx1#
设法解决了这个问题。发生这个问题的原因是我在授权筛选器链设置中有oauth2 ResourceServer()(以启用userInfo端点),并在/oauth2/revoke调用的标头中发送了一个承载令牌:
因此,解决方案是删除此特定筛选器链中的Bearer标记标头或删除oauth2 ResourceServer()。
我还发现Spring Authorization Server目前只支持对/oauth2/revoke端点的基本授权,如果没有在基本的auth头中指定一个客户端秘密,就不能调用这个端点。当您有公共客户端时,这是一个问题。例如,Keycloak提供了一个选项,可以在请求主体以及基本的auth头中指定客户端凭据,并允许省略客户端密码参数