Не удается обработать сбой / успешный вход в систему

#java #spring-boot #oauth-2.0 #jhipster #spring-security-oauth2

#java #spring-boot #oauth-2.0 #jhipster #spring-безопасность-oauth2

Вопрос:

В настоящее время я сталкиваюсь с проблемой обработки любых успешных и неудачных попыток входа в систему на моем сервере Spring Boot REST API.

Я хочу знать, вводит ли пользователь неправильную комбинацию логина / пароля для выполнения некоторого кода (изменения значения в базе данных). В настоящее время методы успешного / неудачного входа вообще не вызываются, но, как ни странно, выход из системы есть…

Для информации, когда я пытаюсь отправить неправильную комбинацию login, у меня есть это в журнале: Handling error: InvalidGrantException, Bad credentials . Итак, возможно ли легко обработать это исключение InvalidGrantException? (в настоящее время мне нужно только отследить этот случай)

Любая помощь была бы высоко оценена!

Примечание: Проект использует OAuth 2 в качестве механизма входа, и я новичок в Spring Boot (исходя из Node.JS :p).

Заранее спасибо!

OAuth2ServerConfiguration

 @Configuration
public class OAuth2ServerConfiguration {

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @Inject
        private Http401UnauthorizedEntryPoint authenticationEntryPoint;

        @Inject
        private AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler;

        @Inject
        private MyLoginSuccessHandler authenticationSuccessHandler;

        @Inject
        private MyLoginFailureHandler authenticationFailureHandler;

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .and()
                .formLogin()
                .loginPage("/oauth/token")
                .successHandler(authenticationSuccessHandler) // Here is the handler for success login
                .failureHandler(authenticationFailureHandler) // Here is the handler for failure login
                .and()
                .logout()
                .logoutUrl("/api/logout")
                .logoutSuccessHandler(ajaxLogoutSuccessHandler) // This handler works fine !
                .and()
                .csrf()
                .disable()
                .headers()
                .frameOptions().disable()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/api/authenticate").permitAll()
                .antMatchers("/api/register").permitAll();
        }
    }
}
  

MyLoginFailureHandler

 @Component
public class MyLoginFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        LOG.info("CATCHING A LOGIN FAILURE !");
        // Not called
        // Here I want to know if the user enter wrong combinaison of login/password
    }
}


@Component
public class MyLoginSuccessHandler implements AuthenticationSuccessHandler {
    private static final Logger LOG = LoggerFactory.getLogger(MyLoginSuccessHandler.class);
    public static final String BEARER_AUTHENTICATION = "Bearer ";

    @Inject
    private TokenStore tokenStore;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                Authentication authentication)
        throws IOException, ServletException {
        LOG.info("CATCHING A LOGIN SUCCESS !");
        // Not called
        // Actually not usefull for me but not working too :/
    }
}
  

======= ПРАВКА 1: =======

I tried to create a new handler specific for oAuth service but without success…

AuthorizationServerConfiguration

 @Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Inject
    private DataSource dataSource;

    @Inject
    private JHipsterProperties jHipsterProperties;

    @Inject
    private OAuth2FailureHandler oAuth2FailureHandler; // Here is my handler

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

    @Inject
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
        throws Exception {

        endpoints
            .tokenStore(tokenStore())
            .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer
            .allowFormAuthenticationForClients()
            .accessDeniedHandler(oAuth2FailureHandler); // Setting up my handler here
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
            .inMemory()
            .withClient(jHipsterProperties.getSecurity().getAuthentication().getOauth().getClientid())
            .scopes("read", "write")
            .authorities(AuthoritiesConstants.ADMIN, AuthoritiesConstants.USER)
            .authorizedGrantTypes("password", "refresh_token", "authorization_code", "implicit")
            .secret(jHipsterProperties.getSecurity().getAuthentication().getOauth().getSecret())
            .accessTokenValiditySeconds(jHipsterProperties.getSecurity().getAuthentication().getOauth().getTokenValidityInSeconds());
    }
}
  

OAuth2FailureHandler

 @Component
public class OAuth2FailureHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        LOG.info("CATCHING A LOGIN FAILURE !");
        // Not called
    }
}
  

======= ПРАВКА 2: =======

Итак, я безуспешно попытался добавить фильтр в свою SecurityConfiguration.

 @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Inject
    private UserDetailsService userDetailsService;

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

    @Inject
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
            .antMatchers(HttpMethod.OPTIONS, "/**")
            .antMatchers("/app/**/*.{js,html}")
            .antMatchers("/bower_components/**")
            .antMatchers("/i18n/**")
            .antMatchers("/content/**")
            .antMatchers("/swagger-ui/index.html")
            .antMatchers("/api/register")
            .antMatchers("/api/activate")
            .antMatchers("/api/account/reset_password/init")
            .antMatchers("/api/account/reset_password/finish")
            .antMatchers("/test/**")
            .antMatchers("/h2-console/**")
            .antMatchers("/api/configuration");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .httpBasic().realmName("xx")
            .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .requestMatchers().antMatchers("/oauth/authorize")
            .and()
                .authorizeRequests()
                .antMatchers("/oauth/authorize").authenticated()
            .and() // <---- I added this 2 lines of codes
                .antMatcher("/**") // <-
                .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); // <-
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
        return new SecurityEvaluationContextExtension();
    }

    // The new filter method
    private Filter ssoFilter() {
        OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter("/oauth/token");

        filter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler() {
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                super.onAuthenticationSuccess(request, response, authentication);
                QueryImpl.LOG.info("CATCHING A LOGIN SUCCESS !");
                // Not called :(
            }
        });


        return filter;
    }
}
  

Комментарии:

1. Вы используете oauth, а не форму входа в систему. Следовательно, настройка обработчика успешного входа в систему на основе формы и ожидание, что он будет работать для oauth, очевидно, не сработает.

2. Спасибо за ваш ответ! Я попытался создать новый класс, реализующий AccessDeniedHandler (см. Мой отредактированный пост), но безуспешно.