#java #spring-boot #keycloak
Вопрос:
У меня есть серверное приложение для нескольких арендаторов, использующее keycloak в качестве поставщика удостоверений личности.
В моих настройках, использующих Java, у меня есть пользовательский решатель конфигурации ключа, в котором я загружаю настройки для развертывания ключа в соответствии с областью каждого клиента, я делаю это через поддомен запроса.
Тогда у каждого арендатора будет поддомен для доступа к интерфейсному приложению, например enterprisea.mydomain.com и enterpriseb.mydomain.com и запрос на серверную часть будет осуществляться с использованием тех же поддоменов, например enterprisea.mydomain.com/api и enterpriseb.mydomain.com/api.
Я хочу изменить этот сценарий, в котором, передавая свой сервер для ответа по URL-адресу, например: back-end-api.mydomain.com и я хотел бы знать, что такое область по маркеру доступа.
У меня есть пользовательский решатель KeyCloakConfigResolver, и я хотел бы изменить его, чтобы получить значение области по маркеру доступа, но SecurityContextHolder.getContext()
оно равно нулю, и я не могу определить причину.
public class KeyCloakConfigResolver implements KeycloakConfigResolver {
@Override
public KeycloakDeployment resolve(HttpFacade.Request request) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
... SecurityContextHolder.getContext() -- NullPointerException
}
}
Устройство для настройки ключа
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class KeycloakConfigAdapter extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Override
protected AuthenticationEntryPoint authenticationEntryPoint() throws Exception {
return new MultitenantKeycloakAuthenticationEntryPoint(adapterDeploymentContext());
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
configuration.addAllowedOriginPattern("*");
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
configuration.addAllowedHeader("*");
configuration.setAllowCredentials(true);
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and().addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), X509AuthenticationFilter.class).exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint())
.and().logout().addLogoutHandler(keycloakLogoutHandler()).logoutUrl("/logout")
.logoutSuccessHandler((HttpServletRequest request, HttpServletResponse response, Authentication authentication)
-> response.setStatus(HttpServletResponse.SC_OK))
.and().apply(new SpringKeycloakSecurityAdapter());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/webjars/**");
}
public static class SpringKeycloakSecurityAdapter extends AbstractHttpConfigurer<SpringKeycloakSecurityAdapter, HttpSecurity> {
@Override
public void init(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/logout", "/", "/unsecured").permitAll()
.anyRequest().authenticated();
}
}
}
ApiBackEndApplication
@SpringBootApplication
public class ApiBackEndApplication {
public static void main(String[] args) {
SpringApplication.run(ApiBackEndApplication.class, args);
}
@Bean
@ConditionalOnMissingBean(KeyCloakConfigResolver.class)
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeyCloakConfigResolver();
}
}