使用Spring Cloud Gateway获取访问令牌,使用Keycloft获取Spring Security



我使用的是带有Spring安全性的Spring云网关和用于访问管理的Key斗篷。我在使用spring cloud gateway获取访问令牌时遇到问题,因为我获得的令牌没有像我从keycloft中的令牌端点获得的所有参数。

当我用所有细节点击密钥斗篷令牌端点时:

http://localhost:8080/auth/realms/myrealm/protocol/openid-连接/令牌

{
"exp": 1595310135,
"iat": 1595309835,
"jti": "0a78d67c-878c-468c-8d03-e003af0350c3",
"iss": "http://localhost:8080/auth/realms/myrealm",
"aud": "account",
"sub": "5c3c71c8-4682-4cd8-8e28-ee66a7edea4e",
"typ": "Bearer",
"azp": "myclient",
"session_state": "af8acabc-b9fb-4d15-9160-b9c613007075",
"acr": "1",
"allowed-origins": [
"http://localhost:8080"
],
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "profile email",
"email_verified": true,
"name": "Vijay 123",
"preferred_username": "vijay",
"given_name": "Vijay",
"family_name": "123"
}

但与此同时,当我试图从Spring Cloud Gateway配置中获得相同的令牌时,我得到了以下令牌:

{
"exp": 1595244254,
"iat": 1595243954,
"auth_time": 1595243954,
"jti": "6d76736d-51d4-4ae7-9c15-55fc2cf9d96a",
"iss": "http://localhost:8080/auth/realms/myrealm",
"aud": "myclient",
"sub": "5c3c71c8-4682-4cd8-8e28-ee66a7edea4e",
"typ": "ID",
"azp": "myclient",
"session_state": "dfbeb8a3-5d8e-4750-b8af-3dd00105cafa",
"acr": "1",
"upn": "vijay",
"email_verified": true,
"address": {},
"name": "Vijay 123",
"groups": [
"offline_access",
"uma_authorization"
],
"preferred_username": "vijay",
"given_name": "Vijay",
"family_name": "123"
}

以下是我使用的配置:

@Bean
public GlobalFilter customGlobalFilter() {
return (exchange, chain) -> exchange.getPrincipal().map(principal -> {
String token = "";
String session = "";
if (principal instanceof OAuth2AuthenticationToken) {
// For Getting token from request
SecurityContextImpl context =
exchange.getSession().block().getAttribute("SPRING_SECURITY_CONTEXT");
DefaultOidcUser principal1 = (DefaultOidcUser) context.getAuthentication().getPrincipal();
token = principal1.getIdToken().getTokenValue();
}
}

令牌值与keycloft中的令牌值不匹配。

是否有其他方法可以从请求中获取OIDC令牌而不是OAuth2令牌?

我可以看到原理是OAuth2AuthenticationToken类型。

我通过创建一个自定义配置类获得了oauth2访问令牌。

步骤1:获取ServerOAuth2AuthorizedClientRepository接口的实例

@Autowired
private ServerOAuth2AuthorizedClientRepository clientRegistrationRepository;

步骤2:应用全局筛选器并从OAuth2AuthorizedClient 获取令牌

// For Getting token from request
SecurityContextImpl context =
exchange.getSession().toProcessor().block().getAttribute("SPRING_SECURITY_CONTEXT");
OAuth2AuthenticationToken oauthToken =
(OAuth2AuthenticationToken) context.getAuthentication();
Mono<OAuth2AuthorizedClient> authorizedClient = clientRegistrationRepository
.loadAuthorizedClient(oauthToken.getAuthorizedClientRegistrationId(),
context.getAuthentication(), exchange);
OAuth2AuthorizedClient client = authorizedClient.toProcessor().block();
String accessToken = client.getAccessToken().getTokenValue();
LOG.info("Access Token value: {}", accessToken);

这是一个完整的配置类,它完美地完成了这项工作。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
import reactor.core.publisher.Mono;
@Configuration
public class GatewayConfig {
private static final Logger LOG = LoggerFactory.getLogger(GatewayConfig.class);
@Autowired
private ServerOAuth2AuthorizedClientRepository clientRegistrationRepository;
@SuppressWarnings("deprecation")
@Bean
public GlobalFilter customGlobalFilter() {
return (exchange, chain) -> exchange.getPrincipal().map(principal -> {
if (principal instanceof OAuth2AuthenticationToken) {
// For Getting token from request
SecurityContextImpl context =
exchange.getSession().toProcessor().block().getAttribute("SPRING_SECURITY_CONTEXT");
OAuth2AuthenticationToken oauthToken =
(OAuth2AuthenticationToken) context.getAuthentication();
Mono<OAuth2AuthorizedClient> authorizedClient = clientRegistrationRepository
.loadAuthorizedClient(oauthToken.getAuthorizedClientRegistrationId(),
context.getAuthentication(), exchange);
OAuth2AuthorizedClient client = authorizedClient.toProcessor().block();
String accessToken = client.getAccessToken().getTokenValue();
LOG.info("Access Token value: {}", accessToken);
}
return exchange;
}).flatMap(chain::filter).then(Mono.fromRunnable(() -> {
}));
}
}

最新更新