如何用Reactive Spring Security终止Auth0会话?遇403错误求助
Spring Security登出接口403重定向问题
我正在Spring Security中实现用户登出功能,访问/logout接口时,应用会重定向到该接口本身,并返回无响应体的403错误。请求中已设置XSRF-TOKEN和SESSION令牌。
SecurityConfiguration.java文件
package com.emmariescurrena.bookesy.api_gateway.config; import java.util.List; import java.util.function.Consumer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.oauth2.client.oidc.web.server.logout.OidcClientInitiatedServerLogoutSuccessHandler; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizationRequestResolver; import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizationRequestResolver; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.authentication.logout.DelegatingServerLogoutHandler; import org.springframework.security.web.server.authentication.logout.SecurityContextServerLogoutHandler; import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler; import org.springframework.security.web.server.authentication.logout.WebSessionServerLogoutHandler; import org.springframework.security.web.server.csrf.CookieServerCsrfTokenRepository; import org.springframework.security.web.server.csrf.CsrfWebFilter; import org.springframework.security.web.server.util.matcher.AndServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.NegatedServerWebExchangeMatcher; import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsConfigurationSource; import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; @Configuration @EnableWebFluxSecurity public class SecurityConfiguration { @Value("${okta.oauth2.audience}") private String audience; @Value("${okta.oauth2.issuer}") private String issuer; @Value("${okta.oauth2.client-id}") private String clientId; @Autowired ReactiveClientRegistrationRepository clientRegistrationRepository; @Bean public SecurityWebFilterChain filterChain(ServerHttpSecurity http) throws Exception { http .cors(cors -> cors.configurationSource(corsConfigurationSource())) .authorizeExchange(authz -> authz .pathMatchers(HttpMethod.POST, "/api/users").permitAll() .anyExchange().authenticated() ) .csrf(csrf -> csrf .csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse()) .requireCsrfProtectionMatcher( new AndServerWebExchangeMatcher( CsrfWebFilter.DEFAULT_CSRF_MATCHER, new NegatedServerWebExchangeMatcher( ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/api/users") ) ) ) ) .oauth2Login(oauth2 -> oauth2 .authorizationRequestResolver(authorizationRequestResolver(this.clientRegistrationRepository)) ) .logout((logout) -> logout .logoutUrl("/logout") .logoutHandler(logoutHandler) .logoutSuccessHandler(oidcLogoutSuccessHandler()) ); return http.build(); } private ServerOAuth2AuthorizationRequestResolver authorizationRequestResolver( ReactiveClientRegistrationRepository clientRegistrationRepository) { var authorizationRequestResolver = new DefaultServerOAuth2AuthorizationRequestResolver(clientRegistrationRepository); authorizationRequestResolver.setAuthorizationRequestCustomizer(authorizationRequestCustomizer()); return authorizationRequestResolver; } private Consumer<OAuth2AuthorizationRequest.Builder> authorizationRequestCustomizer() { return customizer -> customizer .additionalParameters(params -> params.put("audience", audience)); } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(List.of("http://localhost:8080")); configuration.setAllowedMethods(List.of("GET", "POST", "PATCH", "DELETE")); configuration.setAllowedHeaders(List.of("Authorization", "Content-Type", "XSRF-TOKEN", "X-XSRF-TOKEN", "Cookie")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } private DelegatingServerLogoutHandler logoutHandler = new DelegatingServerLogoutHandler( new SecurityContextServerLogoutHandler(), new WebSessionServerLogoutHandler() ); private ServerLogoutSuccessHandler oidcLogoutSuccessHandler() { 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; } }
application.yml配置文件
spring: application: name: api-gateway cloud: gateway: discovery: locator: enabled: true default-filters: - TokenRelay routes: - id: user-service uri: lb://user-service predicates: - Path=/api/users/** security: oauth2: client: registration: okta: client-id: ${CLIENT_ID} client-secret: ${CLIENT_SECRET} provider: okta: issuer-uri: ${ISSUER_URI} okta: oauth2: issuer: ${ISSUER_URI} client-id: ${CLIENT_ID} client-secret: ${CLIENT_SECRET} audience: ${ISSUER_URI}api/v2/ server: port: 8080 eureka: client: service-url: defaultZone: ${EUREKA_CLIENT_SERVICE_URL_DEFAULT_ZONE} logging: level: org: springframework: security: DEBUG
已尝试指定访问/logout所需权限、修改OAuth2作用域、禁用CSRF以及调整logoutSuccessHandler,但均未解决问题。
内容的提问来源于stack exchange,提问作者emmariescurrena
相关产品推荐
相关产品推荐

