Spring Security OAuth2/OIDC RP启动的注销不起作用 [英] Spring Security OAuth2/OIDC RP-initiated logout does not work
本文介绍了Spring Security OAuth2/OIDC RP启动的注销不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使用Spring Security来实现RP发起的注销,从Spring Cloud Gateway到Keyshaak。我的Spring Security配置与Spring Security Reference document中提供的配置几乎相同,转载如下:
@EnableWebFluxSecurity
public class SCGSecurityConfig {
@Autowired
private ReactiveClientRegistrationRepository clientRegistrationRepository;
private ServerLogoutSuccessHandler keycloakLogoutSuccessHandler() {
OidcClientInitiatedServerLogoutSuccessHandler oidcLogoutSuccessHandler =
new OidcClientInitiatedServerLogoutSuccessHandler(this.clientRegistrationRepository);
// Sets the location that the End-User's User Agent will be redirected to
// after the logout has been performed at the Provider
oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}");
return oidcLogoutSuccessHandler;
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.authorizeExchange(authorize -> authorize.anyExchange().authenticated())
.oauth2Login(withDefaults())
.logout(logout -> logout.logoutSuccessHandler(keycloakLogoutSuccessHandler()));
//need to disable on gateway, since we have backend services
http.csrf().disable();
return http.build();
}
}
点击/Logout终结点仅在网关上执行本地注销。我看不到去Keyloak的人会在行动中注销。Keyloak控制台显示用户会话仍处于活动状态。密钥罩发现元数据确实将End_Session_Endpoint显示为True。
下面是Spring Security的相关日志记录。我没有看到任何跟踪级别日志,只有DEBUG(可能代码路径没有命中任何跟踪消息?)
04:01:27.027 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'GET /logout' doesn't match 'null /oauth2/authorization/{registrationId}'
04:01:27.027 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'GET /logout' doesn't match 'null /login/oauth2/code/{registrationId}'
04:01:27.027 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/login', method=GET}
04:01:27.027 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'GET /logout' doesn't match 'GET /login'
04:01:27.027 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: No matches found
04:01:27.027 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/logout', method=GET}
04:01:27.027 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Checking match of request : '/logout'; against '/logout'
04:01:27.027 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: matched
04:01:29.029 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'POST /logout' doesn't match 'null /oauth2/authorization/{registrationId}'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'POST /logout' doesn't match 'null /login/oauth2/code/{registrationId}'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/login', method=GET}
04:01:29.029 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'POST /logout' doesn't match 'GET /login'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: No matches found
04:01:29.029 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/logout', method=GET}
04:01:29.029 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'POST /logout' doesn't match 'GET /logout'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: No matches found
04:01:29.029 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/logout', method=POST}
04:01:29.029 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Checking match of request : '/logout'; against '/logout'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: matched
04:01:29.029 reactor-http-epoll-2 DEBUG anduril WebSessionServerSecurityContextRepository: Found SecurityContext 'SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=Name: [john@acme.com], Granted Authorities: [[ROLE_USER, SCOPE_email, SCOPE_profile]], User Attributes: [{sub=400d12ab-dd15-47ab-b023-35a046e28a75, email_verified=true, name=John Doe, preferred_username=john@acme.com, given_name=John, family_name=Doe, email=john@acme.com}], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[ROLE_USER, SCOPE_email, SCOPE_profile]]]' in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@142a2883'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril LogoutWebFilter: Logging out user 'OAuth2AuthenticationToken [Principal=Name: [john@acme.com], Granted Authorities: [[ROLE_USER, SCOPE_email, SCOPE_profile]], User Attributes: [{sub=400d12ab-dd15-47ab-b023-35a046e28a75, email_verified=true, name=John Doe, preferred_username=john@acme.com, given_name=John, family_name=Doe, email=john@acme.com}], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[ROLE_USER, SCOPE_email, SCOPE_profile]]' and transferring to logout destination
04:01:29.029 reactor-http-epoll-2 DEBUG anduril WebSessionServerSecurityContextRepository: Removed SecurityContext stored in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@142a2883'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril DefaultServerRedirectStrategy: Redirecting to '/login?logout'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'GET /login' doesn't match 'null /oauth2/authorization/{registrationId}'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Request 'GET /login' doesn't match 'null /login/oauth2/code/{registrationId}'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/login', method=GET}
04:01:29.029 reactor-http-epoll-2 DEBUG anduril PathPatternParserServerWebExchangeMatcher: Checking match of request : '/login'; against '/login'
04:01:29.029 reactor-http-epoll-2 DEBUG anduril OrServerWebExchangeMatcher: matched
这里是一个经过编辑的应用程序.yml,
logging.level:
reactor.netty: INFO
org.springframework.cloud.gateway: INFO
org.springframework.security: TRACE
org.springframework.web.FilterChainProxy: INFO
org.springframework.web.reactive.function.client: INFO
spring.cloud.gateway:
httpclient:
wiretap: true
httpserver:
wiretap: true
default-filters:
- name: BasicAuthFilter
routes:
- id: adminservice
uri: http://${ADMIN_SERVICE}/
predicates:
- Path=/admin/**
- id: appservice
uri: http://${APP_SERVICE}/
predicates:
- Path=/app/**
spring.security.oauth2.client:
provider:
keycloak:
issuer-uri: http://${AUTHSERVER}/auth/realms/${REALM}
user-name-attribute: preferred_username
registration:
keycloak-registration:
provider: keycloak
client-id: ${CLIENT_ID}
client-secret: ${CLIENT_SECRET}
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/keycloak"
推荐答案
您能否尝试更新application.yml
并设置显式scope: openid
(以及您的客户端需要的任何其他作用域),如下所示?
spring.security.oauth2.client:
provider:
keycloak:
issuer-uri: http://${AUTHSERVER}/auth/realms/${REALM}
user-name-attribute: preferred_username
registration:
keycloak-registration:
provider: keycloak
client-id: ${CLIENT_ID}
client-secret: ${CLIENT_SECRET}
scope: openid
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/keycloak"
有this issue in Spring Security,它正好处理这个问题。另请参阅my comment to this issue。
我对这个问题的理解如下:
- 对于OAuth2规范,Scope参数是可选的。这就是为什么Spring Security允许它为空/Null,并且不会有任何抱怨。
- 但是,oauth2Login()和logout()功能(例如
OidcClientInitiatedServerLogoutSuccessHandler
)要求作用域参数至少为OpenID。
我还不确定我的理解是否正确。
这篇关于Spring Security OAuth2/OIDC RP启动的注销不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文