尽管设置了Bearer令牌,Spring Cloud Gateway仍重定向到Keycloak登录页面 [英] Spring Cloud Gateway redirects to Keycloak login page although Bearer token is set
问题描述
我正在使用Keycloak作为身份提供者,Spring Cloud Gateway作为API网关以及多个微服务的设置.我可以通过 http://localhost:8050/auth/realms/dev/protocol/openid-connect/token
通过我的网关(重定向到Keycloak)接收JWT.
I am using a setup with Keycloak as Identity Provider, Spring Cloud Gateway as API Gateway and multiple Microservices.
I can receive a JWT via my Gateway (redirecting to Keycloak) via http://localhost:8050/auth/realms/dev/protocol/openid-connect/token
.
我可以使用JWT访问直接位于Keycloak服务器上的资源(例如 http://localhost:8080/auth/admin/realms/dev/users
).但是,当我想使用网关将我中继到相同的资源( http://localhost:8050/auth/admin/realms/dev/users
)时,我会收到Keycloak登录表单作为响应.
I can use the JWT to access a resource directly located at the Keycloak server (e.g. http://localhost:8080/auth/admin/realms/dev/users
).
But when I want to use the Gateway to relay me to the same resource (http://localhost:8050/auth/admin/realms/dev/users
) I get the Keycloak Login form as response.
我的结论是,我的Spring Cloud Gateway应用程序中必须配置有误.
My conclusion is that there must me a misconfiguration in my Spring Cloud Gateway application.
这是网关中的安全配置:
This is the Security Configuration in the Gateway:
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, ReactiveClientRegistrationRepository clientRegistrationRepository) {
// Authenticate through configured OpenID Provider
http.oauth2Login();
// Also logout at the OpenID Connect provider
http.logout(logout -> logout.logoutSuccessHandler(
new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository)));
//Exclude /auth from authentication
http.authorizeExchange().pathMatchers("/auth/realms/ahearo/protocol/openid-connect/token").permitAll();
// Require authentication for all requests
http.authorizeExchange().anyExchange().authenticated();
// Allow showing /home within a frame
http.headers().frameOptions().mode(Mode.SAMEORIGIN);
// Disable CSRF in the gateway to prevent conflicts with proxied service CSRF
http.csrf().disable();
return http.build();
}
}
这是我在网关中的application.yaml:
This is my application.yaml in the Gateway:
spring:
application:
name: gw-service
cloud:
gateway:
default-filters:
- TokenRelay
discovery:
locator:
lower-case-service-id: true
enabled: true
routes:
- id: auth
uri: http://localhost:8080
predicates:
- Path=/auth/**
security:
oauth2:
client:
registration:
keycloak:
client-id: 'api-gw'
client-secret: 'not-relevant-but-correct'
authorizationGrantType: authorization_code
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
scope: openid,profile,email,resource.read
provider:
keycloak:
issuerUri: http://localhost:8080/auth/realms/dev
user-name-attribute: preferred_username
server:
port: 8050
eureka:
client:
service-url:
default-zone: http://localhost:8761/eureka
register-with-eureka: true
fetch-registry: true
如何使网关能够知道用户已通过(使用JWT)进行了身份验证,而不将我重定向到登录页面?
How can I make the Gateway able to know that the user is authenticated (using the JWT) and not redirect me to the login page?
推荐答案
我通过直接与Keycloak通信而无需通过Spring Cloud Gateway中继请求来绕过该问题.
I bypassed the problem by communicating directly with Keycloak without relaying requests to it via Spring Cloud Gateway.
这实际上不是解决方法,但据我所知实际上是最佳实践/完全可以.
That's actually not a workaround but actually best practice/totally ok as far as I understand.
这篇关于尽管设置了Bearer令牌,Spring Cloud Gateway仍重定向到Keycloak登录页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!