Swagger-ui peut s'intégrer à keycloak en utilisant l'option implicit
mode d'authentification. Vous pouvez configurer oauth2 sur swagger-ui afin qu'il vous demande de vous authentifier au lieu de donner directement à swagger-ui le jeton d'accès.
1ère chose, votre swagger doit faire référence à une définition de la sécurité comme :
"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"
}
}
}
Ensuite, vous swagger-ui devez faire référence à un autre paramètre : Avec le js pur, vous pouvez utiliser dans la balise index.html
const ui = SwaggerUIBundle({ ...} );
ui.initOAuth({
clientId: "test-uid",
realm: "Master",
appName: "swagger-ui",
scopeSeparator: " ",
additionalQueryStringParams: {"nonce": "132456"}
})
Dans ce code,
-
authorizationUrl
est le point de terminaison d'autorisation sur votre royaume keycloak
- Vous pouvez adapter la portée à vos besoins.
-
clientId
est un client paramétré avec implicit
mode sur le royaume de Keycloak
- le paramètre supplémentaire
nonce
devrait être aléatoire, mais swagger-ui ne l'utilise pas encore.
J'ajoute ici un exemple si vous voulez faire tout cela sur Spring-boot :
Sur ce framework, vous utiliserez principalement swagger et swagger-ui web-jar de Springfox. Ceci est fait en ajoutant les dépendances :
<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>
Swagger est activé en ajoutant l'annotation swagger2
sur votre classe principale :
@SpringBootApplication
@EnableSwagger2
public class TestSpringApplication {
...
vous pouvez alors mettre en place un Configuration
comme ceci :
@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;
}
}
Il y a beaucoup de choses que vous pouvez mettre à jour dans ce code. C'est principalement le même qu'avant :
-
nonce
qui devrait être une chose aléatoire (swagger-ui ne l'utilise pas encore)
-
clientId
que vous devez configurer en fonction du client que vous avez configuré dans keycloak.
-
basePackage
: Vous devez définir le paquet dans lequel se trouvent tous vos contrôleurs.
- Si vous avez besoin d'une clé api, vous pouvez l'activer et l'ajouter à la liste des schémas de sécurité.
-
LoginEndpoint
qui doit être le point d'accès d'autorisation de votre royaume keycloak.
-
scopeItems
: les scopes que vous souhaitez pour cette authentification.
Il générera la même chose qu'avant : Mise à jour du swagger pour ajouter la securityDefinition et faire que swagger-UI prenne le paramètre pour clientId, nonce, ...
5 votes
Avez-vous réussi à faire fonctionner ce système ? J'ai le même problème en ce moment.
0 votes
Voulez-vous intégrer keycloak avec swagger-UI ? Avez-vous protégé votre définition swagger avec keycloak maintenant ? Peut-être je peux vous aider