Hello,
I have a secured spring backend and an angular frontend. The backend has a
swagger-ui which is accessible without authentification. I would like to be
able to call a backend controller with this swagger-ui, therefore I need an
authentification config in swagger/spring.
I have created two clients in keycloak, one with access type 'public' for
frontend authentification, one with access type 'bearer-only' for the
backend application. The interface between angular and spring was designed
with swagger. The Swagger UI is still visible thanks to
HttpSecurity.authorizeRequests().antMatchers(new
String[]{"/swagger-ui.html", "/swagger/swagger.yaml", "/swagger-resources",
"/swagger-resources/**", "/webjars/springfox-swagger-ui/**"}).permitAll()
I would like to get an access token for calls in Swagger UI. Adding the
java code and swagger yaml configuration from this posting Keycloak
integration in Swagger
<https://stackoverflow.com/questions/41918845/keycloak-integration-in-swagger>
does not work so far. I created a third client in keycloak for the
swagger-ui with a 'public' access type.
My swagger.yaml:
...
securityDefinitions:
OAuth2:
type: oauth2
flow: implicit
authorizationUrl: http://localhost:8080/auth/
scopes:
openid: openid
profile: profile
security:
- OAuth2: [openid, profile]
This is my swagger config class(note: Swagger builds the ui from the provided
yaml file and NOT from the controller classes)
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
private static final Logger LOGGER =
LoggerFactory.getLogger(SwaggerConfiguration.class);
@Bean
WebMvcConfigurer configurer() {
return new WebMvcConfigurer() {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/swagger/**")
.addResourceLocations("classpath:swagger/");
}
};
}
@Primary
@Bean
public SwaggerResourcesProvider swaggerResourcesProvider() {
return () -> {
SwaggerResource resource = new SwaggerResource();
resource.setName("QM-API");
resource.setLocation("/swagger/swagger.yaml");
SwaggerResource models = new SwaggerResource();
models.setName("QM-Models");
models.setLocation("/swagger/qm-common-definitions.yaml");
List<SwaggerResource> resources = new ArrayList<>();
resources.add(resource);
resources.add(models);
return resources;
};
}
@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();
}
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://localhost: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 {
LOGGER.warn("Scope '{}' is not valid (format is scope=description)",
scopeItem);
}
}
return scopes;
}
}
With this configuration I have an 'Authorize' button in my swagger-ui. Pressing
this button opens a modal form, giving me the opportunity to enter a client_id,
and displays checkboxes for the scopes. Pressing the 'Authorize' button in this
form
opens a new tab in my browser, showing the keycloak welcome page. Keycloak does
not show any log error message.
I experimented a bit with the 'flow' in the swagger.yaml. Changing it to
'password' caused the modal form to give more input like 'user' and 'password'
and causing the keycloak to log warn messages, but did not get me further.
What can I do to authenticate the swagger ui against keycloak in order to get
access to the backend?
--
You received this message because you are subscribed to the Google Groups
"Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.