Мы перемещаем аутентификацию наших веб-сервисов SpringBoot с локальной аутентификации jwt на аутентификацию oauth2 с помощью keycloak. Но какое-то время нам нужно использовать обе аутентификации. Если устаревшая аутентификация проверяет токен jwt, все в порядке. В противном случае oauth2AuthenticationManager должен будет проверить его.
В нашем устаревшем коде аутентификации мы используем JWTFilter, который проверяет токен с ключом в файле свойств. Я управлял аутентификацией oAuth2 без провайдера благодаря аннотациям @EnableResourceServer, который создает OAuth2AuthenticationProcessingFilter, но я не могу связать свой JWTFilter с фильтром OAuth2. Даже если JWTFilter проверяет токен, фильтр oauth2 очищает контекст безопасности: SecurityContextHolder.clearContext();
Поэтому моя идея состоит в том, чтобы использовать ProviderManager с двумя менеджерами аутентификации, устаревшим и новым OAuth2:
@Bean
public AuthenticationProvider authenticationProvider(@Qualifier(OAUTH2_AUTHENTICATION_MANAGER) AuthenticationManager oAuth2Authentication,
@Qualifier(LEGACY_AUTHENTICATION_MANAGER) AuthenticationManager legacyAuthentication) {
AuthenticationProvider provider = new AuthenticationProvider() {
private AuthenticationManager oAuth2AuthenticationManager = oAuth2Authentication;
private AuthenticationManager legacyAuthenticationManager = legacyAuthentication;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Authentication authenticate = legacyAuthentication.authenticate(authentication);
if (authenticate.isAuthenticated()) {
return authenticate;
}
return oAuth2AuthenticationManager.authenticate(authentication);
}
@Override
public boolean supports(Class<?> authentication) {
return true; // TODO : check authentication class
}
};
return provider;
}
Я использую этого провайдера следующим образом:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
@Autowired
public void initialize(AuthenticationManagerBuilder builder) {
builder.authenticationProvider(this.authenticationProvider);
}
}
Но это не работает, мой код в провайдере никогда не выполняется. Итак, я пытаюсь инициализировать так:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
...
.and()
.authenticationProvider(this.authenticationProvider)
.authorizeRequests()
...
}
}
, но это тоже не работает. В обоих случаях я получил ошибку 401.
Где я ошибаюсь при использовании моего провайдера? Как использовать моего провайдера с моим 2 AuthenticationManager? Или как связать мой фильтр JWT и фильтр OAUth2 пружины?
Спасибо за помощь!