问题描述
我有一个受Keycloak保护的后端,我想通过swagger-ui访问. Keycloak提供了oauth2隐式和访问代码流,但是我无法使其工作.目前,Keycloak的文档缺少有关 swagger.json 中的 authorizationUrl 和 tokenUrl 应该使用哪个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 auth吗?
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
是密钥斗篷领域的授权端点 - 可以根据需要设置范围
-
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 withimplicit
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键,可以将其启用并将其添加到安全方案列表中
-
LoginEndpoint
:必须是您的密钥斗篷领域的授权端点 -
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 keycloakbasePackage
: 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 realmscopeItems
: 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集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!