授权不适用于带有 OAuth2 客户端 + 资源服务器的网关
Authorization not working in Gateway with OAuth2 Client + Resource Server
我在一个应用程序中使用以下依赖项:Spring-Cloud-Gateway,Spring 启动 OAuth2 客户端,Spring 启动 OAuth2 资源服务器。
我使用以下安全配置:
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, ReactiveClientRegistrationRepository clientRegistrationRepository) {
http.oauth2Login();
http.logout(logout -> logout.logoutSuccessHandler(
new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository)));
http.authorizeExchange()
.pathMatchers("/actuator/health").permitAll()
.pathMatchers("/auth/realms/ahearo/protocol/openid-connect/token").permitAll()
.pathMatchers("/v3/api-docs").permitAll()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(userJwtAuthenticationConverter());
http.csrf().disable().formLogin().disable().httpBasic().disable();
return http.build();
}
@Bean
public UserJwtAuthenticationConverter userJwtAuthenticationConverter() {
return new UserJwtAuthenticationConverter();
}
当我执行调用时,我被正确地建议登录,这工作正常。但只有 Authentication 有效,而不是 Authorization。当我使用调试器时,我可以看到从未调用 userJwtAuthenticationConverter()
方法来使用 JWT 之外的角色。
当我在另一个 application/microservice 中使用相同的方法时,它只是一个 OAuth2 资源服务器,而不是一个 OAuth2 客户端,该方法被正确调用和执行。
application.yaml 中的安全配置在 Spring 云网关应用程序中如下所示:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost/auth/realms/example-realm
jwk-set-uri: http://localhost/auth/realms/example-realm/protocol/openid-connect/certs
client:
registration:
keycloak:
client-id: 'example-proxy-client'
client-secret: 'xxx'
authorizationGrantType: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
scope: openid,profile,email
provider:
keycloak:
issuer-uri: http://localhost/auth/realms/example-realm
user-name-attribute: preferred_username
Spring 云网关应用程序是否可以同时作为 OAuth2 客户端和资源服务器执行,或者我是否在配置应用程序方面犯了错误?
原来我误解了一些基本的 OAuth2 概念。
当我在授权 header(隐式流程)中发送 JWT 时,授权本身工作正常。当我尝试通过浏览器访问资源时,出现了不起作用的情况。
我被重定向到 Keycloak(授权代码流)的登录页面。通过 Keycloak 的登录页面登录后,您不会收到 JWT,而是收到 Keycloak Session ID。 Spring Cloud Gateway 无法基于 Keycloak Session ID 执行授权(不知道如果我想使用授权代码流但我使用的是隐式流,那将如何工作,所以我很好现在)。
我在一个应用程序中使用以下依赖项:Spring-Cloud-Gateway,Spring 启动 OAuth2 客户端,Spring 启动 OAuth2 资源服务器。
我使用以下安全配置:
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, ReactiveClientRegistrationRepository clientRegistrationRepository) {
http.oauth2Login();
http.logout(logout -> logout.logoutSuccessHandler(
new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository)));
http.authorizeExchange()
.pathMatchers("/actuator/health").permitAll()
.pathMatchers("/auth/realms/ahearo/protocol/openid-connect/token").permitAll()
.pathMatchers("/v3/api-docs").permitAll()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(userJwtAuthenticationConverter());
http.csrf().disable().formLogin().disable().httpBasic().disable();
return http.build();
}
@Bean
public UserJwtAuthenticationConverter userJwtAuthenticationConverter() {
return new UserJwtAuthenticationConverter();
}
当我执行调用时,我被正确地建议登录,这工作正常。但只有 Authentication 有效,而不是 Authorization。当我使用调试器时,我可以看到从未调用 userJwtAuthenticationConverter()
方法来使用 JWT 之外的角色。
当我在另一个 application/microservice 中使用相同的方法时,它只是一个 OAuth2 资源服务器,而不是一个 OAuth2 客户端,该方法被正确调用和执行。
application.yaml 中的安全配置在 Spring 云网关应用程序中如下所示:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost/auth/realms/example-realm
jwk-set-uri: http://localhost/auth/realms/example-realm/protocol/openid-connect/certs
client:
registration:
keycloak:
client-id: 'example-proxy-client'
client-secret: 'xxx'
authorizationGrantType: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
scope: openid,profile,email
provider:
keycloak:
issuer-uri: http://localhost/auth/realms/example-realm
user-name-attribute: preferred_username
Spring 云网关应用程序是否可以同时作为 OAuth2 客户端和资源服务器执行,或者我是否在配置应用程序方面犯了错误?
原来我误解了一些基本的 OAuth2 概念。 当我在授权 header(隐式流程)中发送 JWT 时,授权本身工作正常。当我尝试通过浏览器访问资源时,出现了不起作用的情况。 我被重定向到 Keycloak(授权代码流)的登录页面。通过 Keycloak 的登录页面登录后,您不会收到 JWT,而是收到 Keycloak Session ID。 Spring Cloud Gateway 无法基于 Keycloak Session ID 执行授权(不知道如果我想使用授权代码流但我使用的是隐式流,那将如何工作,所以我很好现在)。