SpringAecurity BasicAuthenticationFilter с пользовательским AuthenticationManager - PullRequest
0 голосов
/ 30 ноября 2018

Для BasicAuthenticationFilter я пытаюсь внедрить свой собственный AuthenticationManager.Но когда я отлаживаю запуск, я всегда обнаруживаю, что Class BasicAuthenticationFilter.java не использует мой AuthenticationManager.

Как я могу передать его в BasicAuthenticationFilter?

Я использую SpringBoot 2.1.0 и Spring-Security-Oauth2 2.0.1

AuthorizationConfiguration.java

@Configuration
@EnableAuthorizationServer
public class AuthorizationConfiguration extends 
AuthorizationServerConfigurerAdapter {

@Autowired
private AuthenticationManager authenticationManager;

@Autowired
@Qualifier("passwordEncoder")
private PasswordEncoder passwordEncoder;

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    System.out.println(passwordEncoder.encode("SECRET"));
    clients
    .inMemory()
    .withClient("clientapp")
    .authorizedGrantTypes("client_credentials")
    .authorities("USER")
    .scopes("read", "write")
    .secret(passwordEncoder.encode("SECRET"));

}

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

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

WebSecurityConfiguration.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter{

@Override
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Primary
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManager();
}


@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(16); 
}

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring()
    .antMatchers(ResourceConfiguration.TEST_PATHS);
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    DaoAuthenticationProvider daoAuth = new DaoAuthenticationProvider();
    daoAuth.setPasswordEncoder(passwordEncoder());
    auth.authenticationProvider(daoAuth);
}

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

Ответы [ 3 ]

0 голосов
/ 01 декабря 2018

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

Ваш AuthenticationManager, как, впрочем, может иметь парупроблемы.

Spring Security OAuth создаст две цепочки фильтров (а затем две BasicAuthenticationFilter с, две AuthenticationManager с);один для конечных точек OAuth, например /oauth/token, а другой для всего остального.

Цепочка фильтров, созданная для конечных точек OAuth, принимает значение UserDetailsService, указанное с помощью ClientDetailsServiceConfigurer, и применяет его к указанному AuthenticationManager..

Если я возьму вашу конфигурацию и вставлю ее в свою среду разработки, а затем сделаю:

curl --user clientapp:SECRET localhost:8080/oauth/token -dgrant_type=client_credentials

Тогда он вернется с токеном.

Однако эти клиенты не применяются к AuthenticationManager для остальных запросов.Причина этого в том, что с серверами авторизации часто бывает два разных типа пользователей: клиенты и конечные пользователи.Клиенты должны использовать OAuth API, в то время как пользователям просто нужно использовать веб-приложение (логин и т. Д.).

Это означает, что если вы попробуете:

curl --user clientapp:SECRET localhost:8080

Это не сработает.Набор пользователей не был применен к этой цепочке фильтров.

Если у вас есть конечные точки, отличные от OAuth2, вам необходимо указать группу пользователей в UserDetailsService.Без этого, когда вы попытаетесь поразить эти конечные точки с помощью basic, пользователи не смогут его искать.

Кроме того, по умолчанию AuthenticationManager автоматически подберет ваш PasswordEncoder.Таким образом, вместо вашего WebSecurityConfiguration#configure метода вы можете сделать:

@Bean
public UserDetailsService userDetailsService() {
    return new InMemoryUserDetailsService(User
        .withUsername("user")
        .password(passwordEncoder().encode("password"))
        .role("USER")
        .build());
}

(все еще можно настроить AuthenticationManager, если вам нужно сделать что-то более сложное.)

Пробуя это с вашим опубликованным приложением (снова изменив метод configure в WebSecurityConfiguration для вышеупомянутого), я также могу сделать:

curl --user user:password localhost:8080
0 голосов
/ 05 декабря 2018

Проблема заключалась в том, что я использовал неправильный пакет в своем build.gradle

Чтобы решить эту проблему, я добавил следующий пакет:

build.gradle

implementation("org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:${springBootVersion}")
0 голосов
/ 30 ноября 2018

В вашей WebSecurityConfiguration, authenticationManagerBean () должен возвращать ваш собственный экземпляр компонента AuthenticationManager, а не super.authenticationManager ()?

...