【问题标题】:How to configure bearer-only = true when Using spring-boot-starter-oauth2-client使用spring-boot-starter-oauth2-client时如何配置bearer-only = true
【发布时间】:2021-01-13 14:49:06
【问题描述】:

我正在尝试使用 keycloak 在 spring 云网关中为我的 rest api 设置 o auth2 身份验证。 keyclcoak 将我的请求重定向到登录页面,同时将访问令牌作为不记名令牌传递。在许多地方,我发现解决方案是在 keycloak 适配器中设置 bearer-only = true 。使用 spring-boot-starter-oauth2-client 时在哪里设置它。我不能使用 keycloak-spring-boot-starter 在 application.yml 中设置它

谢谢

【问题讨论】:

  • 是什么让你想使用 spring-security-oauth2-client?客户端模块用于通过 OAuth 2.0 授权流程获取令牌。您正在构建的网关如何知道令牌是什么?如果只是在Authorization 标头中将其提供给网关,那么 spring-security-oauth2-resource-server 就是这样做的。
  • @jzheaux 我正在尝试在网关中为在它后面运行的服务进行身份验证。我设置了一个具有领域、用户和角色的密钥锁服务器,通过我的令牌端点,我可以获得 oauth2 令牌。我想将此令牌与请求一起传递并在网关中进行身份验证。我是这个 spring 框架的新手。
  • 谢谢,这很有帮助。你如何将令牌传递给网关?例如,调用者是否以Authorization 标头将其交给网关?

标签: spring-boot spring-security oauth keycloak api-gateway


【解决方案1】:

我和你有同样的问题。没有找到答案,我开发了一个带有轻量级 keycloak 客户端的过滤器,它调用 keycloak 的 Endpoint introspect 来验证令牌

客户:

public class KeycloakClient {

private final KeycloakConfigurationProperties kcProperties;
private final WebClient client;

public KeycloakClient(final KeycloakConfigurationProperties keycloakConfigurationProperties) {
    this.kcProperties = keycloakConfigurationProperties;
    this.client = WebClient.builder()
                           .baseUrl(keycloakConfigurationProperties.getAuth_server_url())
                           .filter(logRequest())
                           .build();
}

public Mono<Boolean> validateBearerToken(String bearerToken) {
    //todo: improve error management
    return prepareAndRunRequest(bearerToken).retrieve()
                                            .bodyToMono(KeycloakValidationResponse.class)
                                            .flatMap(response -> Mono.just(response.getActive()))
                                            .onErrorResume(WebClientResponseException.class,
                                                           ex -> Mono.just(false));
}

private WebClient.RequestHeadersSpec<?> prepareAndRunRequest(String bearerToken) {

    return client.post()
                 .uri(uriBuilder -> uriBuilder.path("/auth/realms/")
                                              .path(kcProperties.getRealm())
                                              .path("/protocol/openid-connect/token/introspect")
                                              .build())
                 .contentType(MediaType.APPLICATION_JSON)
                 .body(BodyInserters.fromFormData("client_id", kcProperties.getResource())
                                    .with("client_secret", kcProperties.getCredentials_secret())
   

过滤器:

public class ValidationTokenGatewayFilterFactory extends AbstractGatewayFilterFactory<ValidationTokenGatewayFilterFactory.Config> {

private final KeycloakClient client;

public ValidationTokenGatewayFilterFactory(KeycloakClient client) {
    super(Config.class);
    this.client = client;
}

@Override
public GatewayFilter apply(Config config) {
    return (exchange, chain) -> {

        String token = exchange.getRequest()
                               .getHeaders()
                               .get(AUTHORIZATION)
                               .get(0);

        token = token.substring(7);

        log.trace("-- ValidationToken(): token={}", token);

        return client.validateBearerToken(token)
                     .flatMap(validated -> {
                         if (validated) {
                             log.debug("-- ValidationToken(): Token valid");
                             return chain.filter(exchange);
                         } else {
                             log.debug("-- ValidationToken(): Token invalid");
                             exchange.getResponse()
                                     .setStatusCode(HttpStatus.UNAUTHORIZED);

                             return exchange.getResponse()
                                            .setComplete();
                         }
                     });
    };
}

public static class Config {
}

}

您可以在此处找到完整示例:https://gitlab.com/-/snippets/2105967

【讨论】:

    猜你喜欢
    • 2021-10-24
    • 2021-05-25
    • 2021-05-07
    • 2023-01-05
    • 2019-10-25
    • 2018-12-06
    • 2020-03-27
    • 2017-03-17
    • 2017-08-28
    相关资源
    最近更新 更多