securitydefinitions example bearer auth oauth swagger swagger-ui keycloak jboss-tools

oauth - example - Integración de Keycloak en Swagger



swagger securitydefinitions (1)

Swagger-ui puede integrarse con keycloak usando el modo de autenticación implicit . Puede configurar oauth2 en swagger-ui para que le solicite que se autentique en lugar de dar el token de acceso directamente a swagger-ui.

En primer lugar, su arrogancia debe hacer referencia a una definición de seguridad como:

"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" } } }

Luego, swagger-ui necesita hacer referencia a algún otro parámetro: con pure js, puede usar en index.html

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

En este código,

  • permissionUrl es el punto final de autorización en su dominio keycloak
  • Los alcances son algo que puede configurar a sus necesidades
  • clientId es un cliente parametrizado con modo implicit en el dominio keycloak
  • el parámetro adicional nonce debe ser aleatorio, pero swagger-ui no lo usa todavía.

Tendré un ejemplo si quieres hacer todo esto en Spring-boot:

En este marco, utilizarás principalmente el web-jar swagger y swagger-ui de Springfox. Esto se hace agregando las dependencias:

<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 se habilita agregando la anotación swagger2 en su clase principal:

@SpringBootApplication @EnableSwagger2 public class TestSpringApplication { ...

entonces puedes configurar una clase de Configuration como esta:

@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; } }

Hay muchas cosas que puedes actualizar en este código. Esto es principalmente lo mismo que antes:

  • nonce que debería ser aleatorio (swagger-ui no lo usa todavía)
  • clientId que necesita configurar de acuerdo con el cliente que configuró en keycloak
  • basePackage : debe configurar el paquete en el que se encuentran todos los controladores.
  • Si necesita una clave api, puede habilitarla y agregarla a la lista de esquemas de seguridad
  • LoginEndpoint : debe ser el punto final de autorización de su dominio keycloak
  • scopeItems : los ámbitos que desea para esta autenticación.

Generará lo mismo que antes: actualizar Swagger para agregar securityDefinition y hacer que swagger-UI tome el parámetro para clientId, nonce, ...

Tengo un backend protegido por Keycloak al que me gustaría acceder a través de swagger-ui. Keycloak en sí mismo proporciona el flujo implícito o accessCode de oauth2, pero ambos no obtuve trabajo. Actualmente, la documentación de Keycloak no se encuentra en ese punto, la url debería usarse para la autorización de usuario y el identificador de token en swagger.json .

Cada reino dentro de Keycloak ofrece una gran lista de url de configuración al acceder a http://keycloak.local/auth/realms/REALM/.well-known/openid-configuration

Además, he intentado integrar directamente el keycloak js-client dentro de swagger-ui index.html agregando las siguientes líneas:

<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>

También probé algo como esto después de ''Iniciar sesión con éxito''

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

Pero tampoco funciona.

¿Alguna sugerencia de cómo puedo integrar la autenticación keycloak dentro de swagger?