Swagger весенняя аутентификация против брелка - PullRequest
0 голосов
/ 17 октября 2018

У меня есть бэкэнд с пружинным чехлом, защищенный ключом и 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, чтобы получить доступ к бэкэнду?

...