Spring Rest OAuth2 AuthorizationServer: деактивировать пользователя после n неудачных попыток входа - PullRequest
2 голосов
/ 17 октября 2019

Я использую @EnableAuthorizationServer, чтобы получить OAuth2 AuthorizationServer для моего REST API. Оно работает. Теперь я хочу отключить учетные записи пользователей после 10 неудачных попыток входа в систему.

Я пытался настроить пользовательский AuthenticationManager, но он не вызывается.

Это мой AuthorizationServerConfigurerAdapter:

@Configuration
@EnableAuthorizationServer
@EnableResourceServer
public class OAuth2AuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {

  @Autowired
  private AuthenticationClientDetailsService clientDetailsService;

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

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.withClientDetails(clientDetailsService());
  }

  private ClientDetailsService clientDetailsService() {
    return clientDetailsService;
  }

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

  @Bean
  public TokenStore tokenStore() {
    return new InMemoryTokenStore();
  }

  @Bean
  public TokenEnhancer tokenEnhancer() {
    return new CustomTokenEnhancer();
  }

  @Bean
  public AuthenticationManager authenticationManager() {
    return new CustomAuthenticationManager();
  }
}

И это мой манекен AuthenticationManager:

@Log4j
public class CustomAuthenticationManager implements AuthenticationManager {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        log.error("I woz called!");
        authentication.setAuthenticated(true);
        return authentication;
    }

}

Я бы ожидал, что при вызове токена будет вызван CustomAuthenticationManager.authenticate(), чтобы я мог проверить учетные данные и соответствующим образом заблокировать учетную запись. , но метод никогда не вызывается: - (

1 Ответ

0 голосов
/ 18 октября 2019

Единственный способ, с помощью которого я смог это сделать, - это пользовательский TokenEndpointAuthenticationFilter:

AuthenticationManagerProvider

Это необходимо, потому что вам нужен AuthenticationManager для создания экземпляраa TokenEndpointAuthenticationFilter и вы хотите, чтобы экземпляр Spring был создан автоматически.

@Configuration // @Order(99) is important so this bean is initialized before the
@Order(99)     // AuthorizationServerConfigurer at 100           
public class AuthenticationManagerProvider extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

AuthorizationServerConfigurerAdapter

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    AuthenticationManager authenticationManager = authenticationManagerProvider.authenticationManagerBean();
    DefaultOAuth2RequestFactory oAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetailsService);
    CustomAuthenticationFilter filter = new CustomAuthenticationFilter(authenticationManager, oAuth2RequestFactory);

    security.tokenKeyAccess("permitAll()") //
        .checkTokenAccess("isAuthenticated()") //
        .allowFormAuthenticationForClients() //
        .addTokenEndpointAuthenticationFilter(filter);
}

CustomAuthenticationFilter

Вы, вероятно, могли бы специально переопределить успешные и неудачные попытки аутентификации, но в моем случае мне нужно обработать оба, чтобы сбросить количество неудачных попыток на успешную и заблокировать учетную запись, когда достигнут максимум, поэтому я решил переопределить doFilter() напрямую.

Просто не забудьте вызвать супер реализацию в конце, иначе ваш клиент не получит токен!

public class CustomAuthenticationFilter extends TokenEndpointAuthenticationFilter {

    public CustomAuthenticationFilter(AuthenticationManager authenticationManager, OAuth2RequestFactory oAuth2RequestFactory) {
        super(authenticationManager, oAuth2RequestFactory);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // do your thing, then call super-implementation to continue normal authentication flow
        super.doFilter(request, response, chain);
    }
}
...