Spring Boot Rest + Keycloak защита в Докере - не срабатывает перенаправление

Всем привет!

Возникла проблема развертки Spring Boot приложения(микросервисы). По сути роль приложения: обращаться к другому сервису по рест-темплейту и выдавать результат с помощью рест контроллера. К приложению подключен Swagger and Swagger UI, через который происходят авторизация к сервисам через кейлоак(с этим проблем нет), сами сервисы защищены кейклоком через спринг секьюрити (кейклоак поднят в докере).

Логика вызовов методов такова: На каждый метод стоит аннотация с необходимыми ролями пользователя для получения доступа к этому методу. Для того, чтобы обратиться к сервису из вне, необходимо вместе с запросов передать Bearer-token, пример:

введите сюда описание изображения

В данном примере проиходит авторизация через сваггер юай: сваггер обращается к кейлоку, меня перенаправляет на авторизацию кейлока, ввожу данные пользователя, сваггер получает необходимый токен(это все работает исравно). Дальше при отправки запроса токен приходит мне на сервер, где должен получить ответ от кейлока и либо разрешить войти в метод, либо нет. Как раз на данной стадии по сути не происходит ничего, в ответ на реквест к сервису, получаю пустой респонс, а в хедерах можно увидеть, что закончился таймаут на запрос и кейклоак никак не обрабатывал данные. Если с какого-нибудь метода снять аннотацию с необходимыми ролями, то метод через сваггер работает прекрасно. Если отправлять запрос без токена, в ответ получаю респонс, что неавторизованный доступ. Когда мой сервис блы поднят локально, работало все прекрасно, как только сервис поднял в докере, началась данная проблема. Уже перепробовал множество способов, из подозрений то, что бутовое приложение скорее всего желает обратиться к локалхосту, а обращается к имени сервиса в докер-композе.

Какие есть догадки как исправить данную проблему?

Весь материал ниже предоставляю:

Docker-compose:

 keycloak:
image: quay.io/keycloak/keycloak:latest
restart: always
container_name: keycloak
environment:
  DB_VENDOR: POSTGRES
  DB_ADDR: postgres
  DB_DATABASE: keycloak
  DB_USER: postgres
  DB_SCHEMA: public
  DB_PASSWORD: root
  KEYCLOAK_USER: admin
  KEYCLOAK_PASSWORD: root
  KEYCLOAK_IMPORT: /opt/keycloak/my_realm.json
ports:
  - 8080:8080
depends_on:
  - postgres
volumes:
  - ./keycloak:/opt/keycloak
networks:
  - backend

Мой веб сервис в композе:

  edge:
build:
  context: ./edge-service
  dockerfile: Dockerfile-edge
container_name: service-edge
ports:
  - 8888:8888
networks:
  - backend
depends_on:
  - kafka

При запуске приложения, получаю уведомление, что секьюрити работает

введите сюда описание изображения

При обращение к сервису с bearer токеном, получаю лог:

введите сюда описание изображения

В ответ получаю:

введите сюда описание изображения

Пример Рест-Контроллера с методом и маппингом:

@RestController()
@RequestMapping("/json")
public class JsonRestController {
@Autowired
private final RestHandler handler;
@Autowired
private FileRepository fileRepository;

public JsonRestController(RestHandler restHandler) {
    this.handler = restHandler;
}

@RolesAllowed({"admin", "user"})
@GetMapping(value = "/id/{id}", produces = "application/json")
@ResponseStatus(HttpStatus.OK)
public Device findById(@PathVariable("id") String id) {
    return handler.findById(id);
}

Конфиг Секьюрити:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

@Autowired
public void configureGlobal(
        AuthenticationManagerBuilder auth) {
    KeycloakAuthenticationProvider keycloakAuthenticationProvider
            = keycloakAuthenticationProvider();
    keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
            new SimpleAuthorityMapper());
    auth.authenticationProvider(keycloakAuthenticationProvider);
}

@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
    return new KeycloakSpringBootConfigResolver();
}

@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
    return new RegisterSessionAuthenticationStrategy(
            new SessionRegistryImpl());
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
    http.authorizeRequests()
            .anyRequest()
            .permitAll();
    http.csrf().disable();
}

}

Конфиг сваггера: (с ним проблем нет, просто для сведения)

@Configuration
public class SpringFoxConfig {

    @Value("${keycloak.auth-server-url}")
    private String AUTH_SERVER;
    @Value("${keycloak.credentials.secret}")
    private String CLIENT_SECRET;
    @Value("${keycloak.resource}")
    private String CLIENT_ID;
    @Value("${keycloak.realm}")
    private String REALM;

    private static final String OAUTH_NAME = "spring_oauth";
    private static final String GROUP_NAME = "MICRO-api";
@Bean
public Docket api() {
    return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.onboarding.edgeservice.controllers"))
            .paths(PathSelectors.any())
            .build()
            .apiInfo(apiInfo())
            .securitySchemes(Arrays.asList(securityScheme()))
            .securityContexts(Arrays.asList(securityContext()));
}

@Bean
public SecurityConfiguration security() {
    return SecurityConfigurationBuilder.builder()
            .realm(REALM)
            .clientId(CLIENT_ID)
            .clientSecret(CLIENT_SECRET)
            .appName(GROUP_NAME)
            .scopeSeparator(" ")
            .build();
}

private SecurityScheme securityScheme() {
    GrantType grantType =
            new AuthorizationCodeGrantBuilder()
                    .tokenEndpoint(new TokenEndpoint("http://localhost:8080/auth" + "/realms/" + REALM + "/protocol/openid-connect/token", GROUP_NAME))
                    .tokenRequestEndpoint(
                            new TokenRequestEndpoint("http://localhost:8080/auth" + "/realms/" + REALM + "/protocol/openid-connect/auth", CLIENT_ID, CLIENT_SECRET))
                    .build();

    return new OAuthBuilder()
            .name(OAUTH_NAME)
            .grantTypes(Arrays.asList(grantType))
            .build();
}

private AuthorizationScope[] scopes() {
    AuthorizationScope[] scopes = {
    };
    return scopes;
}

private SecurityContext securityContext() {
    return SecurityContext.builder()
            .securityReferences(Arrays.asList(new SecurityReference(OAUTH_NAME, scopes())))
            .forPaths(PathSelectors.any())
            .build();
}

private ApiInfo apiInfo() {
    return new ApiInfo(
            "My onboarding",
            "Some custom description of API.",
            "1.0.0",
            "Terms of service",
            new Contact("Sergey Vasilchenko", "www.example.com", "[email protected]"),
            "License of API", "API license URL", Collections.emptyList());
}

}

Кейклоак пропертя в спринговых пропертях:

    keycloak.auth-server-url=http://keycloak:8080/auth
keycloak.realm=onboarding
keycloak.resource=dev-client
keycloak.ssl-required=external
keycloak.credentials.secret=<secret code>
keycloak.use-resource-role-mappings=true
keycloak.bearer-only=true

Прошу помощи) если еще необходимо будет какие-то данные - предоставлю)


Ответы (0 шт):