You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Keycloak扩展中用Swagger/OpenAPI生成自定义API文档?

解决Keycloak自定义扩展Swagger/OpenAPI文档不显示问题

1. 核心问题分析

Keycloak扩展作为插件部署,并非独立Quarkus应用,因此不会自动读取扩展内的application.properties,且默认的OpenAPI扫描逻辑不会覆盖扩展中的JAX-RS资源,这是文档无法生成的核心原因。

2. 为自定义JAX-RS资源添加OpenAPI注解

确保你的资源类和方法上正确标注SmallRye OpenAPI注解,让扫描机制识别API信息:

import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.jboss.resteasy.annotations.cache.NoCache;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("custom")
public class CustomRealmResource {

    @GET
    @NoCache
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(summary = "获取自定义领域数据", description = "返回当前领域的自定义业务信息")
    @APIResponse(responseCode = "200", description = "成功获取数据")
    public String getCustomData(
            @Parameter(description = "目标领域ID", required = true)
            @PathParam("realm") String realm) {
        return "{\"message\": \"Custom data for realm " + realm + "\"}";
    }
}

3. 手动暴露OpenAPI文档端点

Keycloak不会自动扫描扩展资源生成文档,需要自定义资源来暴露OpenAPI模型:

import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition;
import org.eclipse.microprofile.openapi.annotations.info.Info;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.jboss.resteasy.annotations.cache.NoCache;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import org.eclipse.microprofile.openapi.OASFactory;

@OpenAPIDefinition(
        info = @Info(title = "Keycloak自定义领域API", version = "1.0.0"),
        tags = @Tag(name = "custom", description = "自定义领域业务接口")
)
@Path("openapi")
public class CustomOpenApiResource {

    @GET
    @NoCache
    @Produces(MediaType.APPLICATION_JSON)
    public OpenAPI getOpenApi() {
        // 可通过SmallRye API自动扫描扩展内的JAX-RS资源,此处示例为手动构建
        return OASFactory.createObject(OpenAPI.class)
                .info(OASFactory.createInfo()
                        .title("Keycloak自定义领域API")
                        .version("1.0.0"));
    }
}

将这个类通过RealmResourceProviderFactory注册后,即可通过/admin/realms/{realm}/openapi访问JSON格式的OpenAPI文档。

4. 部署自定义Swagger UI

复用Keycloak内置的Swagger UI资源,自定义入口页面指向你的OpenAPI文档:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("swagger-ui")
public class CustomSwaggerUiResource {

    @GET
    @Produces(MediaType.TEXT_HTML)
    public Response getSwaggerUi() {
        String html = "<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>自定义Keycloak API文档</title>\n" +
                "    <link rel=\"stylesheet\" type=\"text/css\" href=\"/admin/swagger-ui/swagger-ui.css\" />\n" +
                "    <script src=\"/admin/swagger-ui/swagger-ui-bundle.js\"></script>\n" +
                "    <script src=\"/admin/swagger-ui/swagger-ui-standalone-preset.js\"></script>\n" +
                "</head>\n" +
                "<body>\n" +
                "    <div id=\"swagger-ui\"></div>\n" +
                "    <script>\n" +
                "        window.onload = function() {\n" +
                "            const realm = window.location.pathname.split('/')[3];\n" +
                "            const ui = SwaggerUIBundle({\n" +
                "                url: `${window.location.origin}/admin/realms/${realm}/openapi`,\n" +
                "                dom_id: '#swagger-ui',\n" +
                "                presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],\n" +
                "                layout: \"StandaloneLayout\"\n" +
                "            });\n" +
                "        };\n" +
                "    </script>\n" +
                "</body>\n" +
                "</html>";
        return Response.ok(html).build();
    }
}

注册后,通过/admin/realms/{realm}/swagger-ui即可访问自定义API的Swagger UI界面。

5. 依赖版本适配

确保扩展使用的SmallRye OpenAPI版本与Keycloak内置版本一致,避免冲突,建议使用provided scope复用Keycloak的依赖:

<dependency>
    <groupId>io.smallrye</groupId>
    <artifactId>smallrye-open-api-jaxrs</artifactId>
    <version>${smallrye-open-api.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-swagger-ui</artifactId>
    <version>${quarkus.version}</version>
    <scope>provided</scope>
</dependency>

版本号可参考Keycloak官方BOM文件。


内容的提问来源于stack exchange,提问作者AmiR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:04:53