Не работает авторизация в Docker

Разбираясь с keycloak по этому видео, столкнулся с проблемой. А именно, при запусуке без докера у меня нормально работает авторизация, и запросы по URL /api/v1/events/** без нее не пропускаются. Но при запуске в docker у меня спокойно получается отправлять запросы по этому URL. Проблема сохраняется, даже если сделать самую простую конфигурацию:

 @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().authenticated()
                )
                .httpBasic(Customizer.withDefaults());
        return http.build();
    }

В логах нет никакой ошибки. Не знаю, что делать в такой ситуации.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers("/actuator/**").permitAll()
                    .requestMatchers("/api/v1/events/**").authenticated()
                    .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 -> oauth2
                    .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter()))
            );
    return http.build();
}

private JwtAuthenticationConverter jwtAuthenticationConverter() {
    var converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(new KeycloakJwtAuthenticationConverter());
    return converter;
}

public class KeycloakJwtAuthenticationConverter implements Converter<Jwt, Collection<GrantedAuthority>> {

@Override
public Collection<GrantedAuthority> convert(Jwt jwt) {
    List<String> roles = jwt.getClaimAsStringList("roles");
    if (roles == null) {
        return Collections.emptyList();
    }

    return roles.stream()
            .map(SimpleGrantedAuthority::new)
            .collect(Collectors.toList());
}

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

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

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

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


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

Автор решения: AlekseiGaile

В Docker-среде localhost внутри контейнера не указывает на вашу хост-машину, а только на сам контейнер. Поэтому, когда приложение пытается обратиться к http://localhost:9090, оно ищет сервис внутри себя, а не в другом контейнере.

В файле application.properties (или application.yml) нужно заменить localhost на имя контейнера, в котором работает нужный сервис. Например, если Keycloak запущен в контейнере с именем keycloak, то:

http://keycloak:9090/....

Docker создаёт внутреннюю сеть, где контейнеры могут обращаться друг к другу по их именам. Поэтому keycloak в данном случае — это DNS-имя контейнера в этой сети.

Но при этом, если вы будете разворачивать Keycloak в докере, а приложение запускать в intellij idea, то тогда надо использовать localhost. Можно создать разные application.properties с профилем dev и prod, для примера, и один использовать в Докере, а другой для локальной разработки.

→ Ссылка