У меня есть бэкэнд с пружинным чехлом, защищенный ключом и oauth2.Фронтенд - это угловое приложение.В keycloak есть два клиента, один с типом доступа public для аутентификации веб-интерфейса, другой с типом доступа только для носителя для бэкэнд-приложения.
Интерфейс между angular и spring разработан с помощью swagger.Интерфейс Swagger по-прежнему виден благодаря
HttpSecurity.authorizeRequests().antMatchers(new String[]{"/swagger-ui.html", "/swagger/swagger.yaml", "/swagger-resources", "/swagger-resources/**", "/webjars/springfox-swagger-ui/**"}).permitAll()
Когда я вызываю службу отдыха, я получаю ошибку 401, потому что серверная часть защищена.Поэтому я хотел бы получить токен доступа для звонков в Swagger UI.Добавление кода java и конфигурации swamger yaml из этого сообщения Интеграция Keycloak в Swagger пока не работает.
Я создал третий клиент в keycloak для swagger-ui с «открытым» типом доступа.
swagger.yaml
...
securityDefinitions:
OAuth2:
type: oauth2
flow: implicit
authorizationUrl: http://localhost:8080/auth/
scopes:
openid: openid
profile: profile
security:
- OAuth2: [openid, profile]
Swagger-Config: (примечание: Swagger создает пользовательский интерфейс из предоставленного файла yaml, а НЕ из классов контроллера)
@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;
}
}
В этой конфигурации у меня есть кнопка «Авторизоваться» в моем интерфейсе пользователя.Нажатие на эту кнопку открывает модальную форму, давая мне возможность ввести client_id, и отображает флажки для областей.Нажатие на кнопку «Авторизовать» в этой форме открывает в моем браузере новую вкладку, показывающую страницу приветствия Keycloak.Keycloak не показывает сообщение об ошибке журнала.
Я немного поэкспериментировал с «потоком» в swagger.yaml.Изменение его на «пароль» привело к тому, что модальная форма давала больше ввода, например, «пользователь» и «пароль», и заставило клавиатуру регистрировать предупреждающие сообщения, но больше не помогло.
Что я могу сделать, чтобы аутентифицироваться с помощью Keycloak, чтобы получить доступ к бэкэнду?