Swagger 中的 Keycloak 集成 [英] Keycloak integration in Swagger

查看:18
本文介绍了Swagger 中的 Keycloak 集成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个受 Keycloak 保护的后端,我想通过 swagger-ui 访问它.Keycloak 提供了 oauth2 隐式和访问代码流,但我无法使其工作.目前,Keycloak 的文档缺乏关于 swagger.json 中的 authorizationUrltokenUrl 应该使用哪个 url 的文档.

I have a Keycloak protected backend that I would like to access via swagger-ui. Keycloak provides the oauth2 implicit and access code flow, but I was not able to make it work. Currently, Keycloak's documentation is lacking regarding which url should be used for authorizationUrl and tokenUrl within swagger.json.

Keycloak 中的每个领域都通过访问 提供了大量的配置 URL 列表http://keycloak.local/auth/realms/REALM/.well-known/openid-configuration

Each realm within Keycloak offers a huge list of configuration urls by accessing http://keycloak.local/auth/realms/REALM/.well-known/openid-configuration

此外,我尝试通过添加以下几行将 keycloak js-client 直接集成到 swagger-ui index.html 中:

Furthermore I've tried to directly integrate the keycloak js-client within swagger-ui index.html by adding the following lines:

<script src="keycloak/keycloak.js"></script>
<script>
  var keycloak = Keycloak('keycloak.json');
    keycloak.init({ onLoad: 'login-required' })
      .success(function (authenticated) {
        console.log('Login Successful');
        window.authorizations.add("oauth2", new ApiKeyAuthorization("Authorization", "Bearer " + keycloak.token, "header"));
      }).error(function () {
        console.error('Login Failed');
        window.location.reload();
      }
    );
 </script>

在登录成功"之后我也尝试过类似的操作

I also tried something like this after 'Login Successful'

swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("Authorization", "Bearer " + keycloak.token, "header"));

但它也不起作用.

对于如何在 swagger 中集成 keycloak 身份验证有什么建议吗?

Any suggestions how I can integrate keycloak auth within swagger?

推荐答案

Swagger-ui 可以使用 implicit 身份验证模式与 keycloak 集成.您可以在 swagger-ui 上设置 oauth2,以便它会要求您进行身份验证,而不是直接向 swagger-ui 提供访问令牌.

Swagger-ui can integrate with keycloak using the implicit authentication mode. You can setup oauth2 on swagger-ui so that it will ask you to authenticate instead of giving swagger-ui the access token directly.

第一件事,你的招摇需要引用一个安全定义,如:

1st thing, your swagger need to reference a Security definition like:

"securityDefinitions": {
    "oauth2": {
        "type":"oauth2",
        "authorizationUrl":"http://172.17.0.2:8080/auth/realms/master/protocol/openid-connect/auth",
        "flow":"implicit",
        "scopes": {
            "openid":"openid",
            "profile":"profile"
        }
    }
}

那么,你swagger-ui需要引用一些其他的参数:纯js,你可以在index.html

Then, you swagger-ui need to reference some other parameter: With the pure js, you can use in the index.html

const ui = SwaggerUIBundle({ ...} );

ui.initOAuth({
    clientId: "test-uid",
    realm: "Master",
    appName: "swagger-ui",
    scopeSeparator: " ",
    additionalQueryStringParams: {"nonce": "132456"}
})

在这段代码中,

  • authorizationUrl 是 keycloak 领域的授权端点
  • 范围是您可以根据需要设置的内容
  • clientId 是一个在 keycloak 领域使用 implicit 模式参数化的客户端
  • 附加参数 nonce 应该是随机的,但是 swagger-ui 还没有使用它.
  • authorizationUrl is the authorization endpoint on your keycloak realm
  • Scopes are something you can set to your needs
  • clientId is a client parametrized with implicit mode on keycloak realm
  • the additional parameter nonce should be random, but swagger-ui don't use it yet.

如果您想在 Spring-boot 上执行所有这些操作,我会在此处添加一个示例:

I add here an example if you want to do all this on Spring-boot:

在这个框架上,您将主要使用 Springfox 的 swagger 和 swagger-ui web-jar.这是通过添加依赖项来完成的:

On this framework, you will mainly use swagger and swagger-ui web-jar from Springfox. This is done by adding the dependencies:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.0</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.0</version>
</dependency>

通过在主类上添加注释 swagger2 来启用 Swagger:

Swagger is enable by adding the annotation swagger2 on your main class:

@SpringBootApplication
@EnableSwagger2
public class TestSpringApplication {
    ...

然后你可以像这样设置一个Configuration类:

then you can setup a Configuration class like this:

@Configuration
public class SwaggerConfigurer {

    @Bean
    public SecurityConfiguration securityConfiguration() {

        Map<String, Object> additionalQueryStringParams=new HashMap<>();
        additionalQueryStringParams.put("nonce","123456");

        return SecurityConfigurationBuilder.builder()
            .clientId("test-uid").realm("Master").appName("swagger-ui")
            .additionalQueryStringParams(additionalQueryStringParams)
            .build();
    }

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.example.testspring"))
            .paths(PathSelectors.any())
            .build().securitySchemes(buildSecurityScheme()).securityContexts(buildSecurityContext());
    }

    private List<SecurityContext> buildSecurityContext() {
        List<SecurityReference> securityReferences = new ArrayList<>();

        securityReferences.add(SecurityReference.builder().reference("oauth2").scopes(scopes().toArray(new AuthorizationScope[]{})).build());

        SecurityContext context = SecurityContext.builder().forPaths(Predicates.alwaysTrue()).securityReferences(securityReferences).build();

        List<SecurityContext> ret = new ArrayList<>();
        ret.add(context);
        return ret;
    }

    private List<? extends SecurityScheme> buildSecurityScheme() {
        List<SecurityScheme> lst = new ArrayList<>();
        // lst.add(new ApiKey("api_key", "X-API-KEY", "header"));

        LoginEndpoint login = new LoginEndpointBuilder().url("http://172.17.0.2:8080/auth/realms/master/protocol/openid-connect/auth").build();

        List<GrantType> gTypes = new ArrayList<>();
        gTypes.add(new ImplicitGrant(login, "acces_token"));

        lst.add(new OAuth("oauth2", scopes(), gTypes));
        return lst;
    }

    private List<AuthorizationScope> scopes() {
        List<AuthorizationScope> scopes = new ArrayList<>();
        for (String scopeItem : new String[]{"openid=openid", "profile=profile"}) {
            String scope[] = scopeItem.split("=");
            if (scope.length == 2) {
                scopes.add(new AuthorizationScopeBuilder().scope(scope[0]).description(scope[1]).build());
            } else {
                log.warn("Scope '{}' is not valid (format is scope=description)", scopeItem);
            }
        }

        return scopes;
    }
}

您可以在此代码中更新很多内容.这主要和之前一样:

There is a lot of thing you can update in this code. This is mainly the same as before:

  • nonce 这应该是一个随机的东西(swagger-ui 还没有使用它)
  • clientId 您需要根据您在 keycloak 中设置的客户端进行设置
  • basePackage:您需要设置所有控制器所在的包
  • 如果您需要 api-key,您可以启用它并将其添加到安全方案列表中
  • LoginEndpoint:需要是你keycloak领域的授权端点
  • scopeItems:此身份验证所需的范围.
  • nonce which should be a random thing (swagger-ui don't use it yet)
  • clientId which you need to setup accordingly to the client you setup in keycloak
  • basePackage: You need to set the package in which all your controller are
  • If you need an api-key, you can enable it and add it on the security scheme list
  • LoginEndpoint: that need to be the authorization endpoint of you keycloak realm
  • scopeItems: the scopes you want for this authentication.

它会生成和以前一样的东西:更新 swagger 以添加 securityDefinition 并使 swagger-UI 接受 clientId、nonce、...的参数.

It will generate the same thing as before: Updating the swagger to add the securityDefinition and make swagger-UI take the parameter for clientId, nonce, ...

这篇关于Swagger 中的 Keycloak 集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆