Spring Boot: используйте устаревшую аутентификациюManager и новую аутентификацию oAuth2 - PullRequest
0 голосов
/ 21 марта 2020

Мы перемещаем аутентификацию наших веб-сервисов 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 пружины?

Спасибо за помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...