Spring OAuth2 Security - учетные данные клиента - пользовательский поставщик проверки подлинности - PullRequest
0 голосов
/ 13 февраля 2019

Я пишу сервис аутентификации в нашей сервисной архитектуре, которая будет в основном реализацией Spring OAuth2 Authorization Server.Исходя из этого, мне нужно будет аутентифицировать предоставленные учетные данные по множеству различных источников для поддержки устаревшей среды.

Я в основном сконцентрирован на использовании потока учетных данных клиента, где пользователи (другие службы) будут использовать свои собственные учетные данные для получения токенаи на данный момент не потребуется авторизация или обновление OAuth2.

Я успешно смог запустить приложение Spring Boot, защищенное Spring Security (@EnableWebSecurity).Я также успешно настроил Сервер авторизации (@EnableAuthorizationServer), который предоставляет необходимые конечные точки (/oauth/token) для предоставления токена.Я был в состоянии настроить Сервер авторизации с помощью памяти и пользовательского ClientDetailsService для успешного получения токена.Это все лишь для того, чтобы продемонстрировать себе, что я могу заставить что-то работать.

Моя проблема в том, что мне нужно аутентифицировать учетные данные на основе собственного источника.У меня нет прямого доступа к паролям и, конечно, я не знаю, как они кодируются.

После копания в коде Spring я мог видеть, что через DaoAuthenticationProvider он выполняет аутентификацию, вызывая PasswordEncoder.matches(),К сожалению, я не получаю пароль от ClientDetailsService, и при этом я не знаю, как пароль закодирован, если я это сделал, поэтому пользовательский PasswordEncoder не очень мне помогает (также мне нужно было бы сопоставить несколькими способами только содин PasswordEncoder).Итак, у меня осталось определение собственного AuthenticationProvider (или AuthenticationManager).

Я смог реализовать свой собственный AuthenticationProvider и предоставить его для конфигурации Spring Security.Это сработало отлично, и я смог перенести аутентификацию на моего собственного провайдера, который может делать все, что я сочту нужным (например, делегировать другой сервис для аутентификации), но это работало только для конечных точек не OAuth2.

Теперь здесь все начинает разваливаться.По какой-то причине я не могу заставить конечную точку /oauth/token использовать определенные AuthenticationManager или AuthenticationProvider s, которые я предоставляю.По умолчанию он всегда равен AuthenticationManger с AnonymousAuthenticationProvider и DaoAuthenticationProvider.

WebSecurity

Не очень интересно здесь.Я выставляю менеджер аутентификации глобально в попытке зарегистрировать его в конфигурации OAuth2.Я оставил в некотором закомментированном коде, чтобы показать некоторые другие вещи, которые я пробовал, но все они в значительной степени выполняют одно и то же: он работает со всем, кроме конечных точек OAuth2.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public AuthenticationProvider customAuthenticationProvider;

    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
//      return new ProviderManager(Arrays.asList(customAuthenticationProvider));
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest()
            .authenticated()
        .and()
            .httpBasic();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .authenticationProvider(customAuthenticationProvider);
    }

//   @Autowired
//   public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//       auth.authenticationProvider(customAuthenticationProvider);
//   }
}

AuthServer

Я сократил это до того, что, как я считаю, должно быть правильной конфигурацией.Я намеренно пропустил ClientDetailsService, так как это часть конфигурации провайдера, и она работает правильно.Я игнорирую TokenStore и использую значения по умолчанию, пока не смогу получить аутентификацию.Опять же, authenticationManager здесь должно быть глобальным, предоставляемым WebSecurity.Я также попытался создать новый ProviderManager в конфигураторе конечных точек, но у меня это тоже не сработало.

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {        
        oauthServer
            .tokenKeyAccess("permitAll()")
            .checkTokenAccess("permitAll()")
        ;
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }
}

Я также безуспешно пытался расширить AuthorizationServerSecurityConfiguration:

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig2 extends AuthorizationServerSecurityConfiguration {

    @Autowired
    public AuthenticationProvider customAuthenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthenticationProvider);
    }
}

Я бы ожидал, что мой пользовательский AuthenticationProvider будет отображаться в списке, но он не будет отображаться со всем, что я пробовал.

Это может быть преднамеренным, но если это так, топравильный способ предоставления пользовательских схем аутентификации?

Я бы действительно хотел этого избежать, но действительно ли я должен реализовать собственный фильтр и обойти все приятные вещи, которые предоставляет Spring?Если да, как бы я поступил так?

1 Ответ

0 голосов
/ 26 февраля 2019

Я закончил настройку дополнительного BasicAuthenticationFilter для конечной точки токена.Для меня это немного грязно, так как теперь в цепочке фильтров безопасности есть два одинаковых фильтра, но это делает свое дело.

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private UserService userService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer
            .tokenKeyAccess("isAuthenticated()")
            .checkTokenAccess("isAuthenticated()");

        // override the default basic authentication filter in order to provide
        // a custom authentication manager
        oauthServer.addTokenEndpointAuthenticationFilter(new BasicAuthenticationFilter(authenticationManager, new BasicAuthenticationEntryPoint()));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...