我目前在处理 Spring Boot REST API 服务器上的任何成功和失败登录尝试时遇到问题。
我想知道用户是否输入登录 / 密码的错误组合,以便执行一些代码(在数据库)。当前,成功/失败方法根本没有被调用,但是奇怪的是,注销是...
有关信息,当我尝试发送错误的登录组合时,我将其记录在日志中: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:=======
我试图创建一个专门针对oAuth服务的新处理程序,但没有成功...
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;
}
}