Не работает авторизация в 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 шт):
В 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, для примера, и один использовать в Докере, а другой для локальной разработки.



