我想在我的项目中设置自定义AuthenticationFailureHandler。即使我将authenticationFailureHandler配置如下,但在登录失败时也无法正确接收。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
..................
@Inject
private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler;
..................
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated().and()
.formLogin().loginPage("/signin").failureHandler(ajaxAuthenticationFailureHandler)
.permitAll()
.failureUrl("/signin")
.defaultSuccessUrl("/search").and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/signout"))
.logoutSuccessUrl("/signin")
.permitAll().and().csrf();
}
我的自定义AuthenticationFailureHandler类
@Component
public class AjaxAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
// Custom code
}
}
当我调试应用程序时,方法onAuthenticationFailure
从SimpleUrlAuthenticationFailureHandler
调用,但不在我的自定义AjaxAuthenticationFailureHandler
中调用,即使我扩展了相同的SimpleUrlAuthenticationFailureHandler
。
解决问题可能是错误或错过任何配置?
答案 0 :(得分:4)
在这种情况下,当我们设置自定义AjaxAuthenticationFailureHandler
然后我们配置failureUrl("/signin")
时,配置failureUrl("/signin")
将使用新{{1}覆盖已配置的AjaxAuthenticationFailureHandler
}}。
这是SimpleUrlAuthenticationFailureHandler
和failureUrl
方法的实施,如failureHandler
。
AbstractAuthenticationFilterConfigurer
如果我们只设置如下 public abstract class AbstractAuthenticationFilterConfigurer<B extends HttpSecurityBuilder<B>, T extends AbstractAuthenticationFilterConfigurer<B, T, F>, F extends AbstractAuthenticationProcessingFilter> extends AbstractHttpConfigurer<T, B> {
...........
private AuthenticationFailureHandler failureHandler;
private String failureUrl;
..........
public final T failureUrl(String authenticationFailureUrl) {
T result = failureHandler(new SimpleUrlAuthenticationFailureHandler(authenticationFailureUrl));
this.failureUrl = authenticationFailureUrl;
return result;
}
public final T failureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
this.failureUrl = null;
this.failureHandler = authenticationFailureHandler;
return getSelf();
}
}
,我们将设置自定义AjaxAuthenticationFailureHandler。
failurehandler
如果我们要设置失败网址,我们可以使用 .formLogin().loginPage("/signin")
.permitAll()
.failureHandler(ajaxAuthenticationFailureHandler)
.defaultSuccessUrl("/search").and()
在自定义AjaxAuthenticationFailureHandler
中设置它,该setDefaultFailureUrl(String defaultFailureUrl)
是从其父类SimpleUrlAuthenticationFailureHandler
派生的。
答案 1 :(得分:0)
您可以在AjaxAuthenticationFailureHandler
类中创建构造函数,并将defaultFailureUrl
参数向下传递给您扩展的父级(SimpleUrlAuthenticationFailureHandler
)。您的AjaxAuthenticationFailureHandler
课程如下: -
@Component
public class AjaxAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
public AjaxAuthenticationFailureHandler (String defaultFailureUrl) {
super(defaultFailureUrl);
}
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
// Custom code
}
}
您的配置块将如下所示: -
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/signin")
.failureHandler(new AjaxAuthenticationFailureHandler("/signin?auth=failure") // or whatever is a sensible url
.permitAll()
.defaultSuccessUrl("/search").and()
...
请注意,将"/signin?auth=failure"
添加到authorizeRequests()
部分非常重要,否则控制器将不会选择auth
参数,例如。
.and()
.authorizeRequests()
.antMatchers(
"/css/**",
"/js/**",
"/images/**",
"/signin**" // REALLY IMPORTANT !!!
).permitAll()
有关详细信息,请参阅https://stackoverflow.com/a/39618113/1692179。
您的控制器现在可以检查auth
参数,例如
@Controller
public class SigninController
@RequestMapping(value="/login", method = RequestMethod.GET)
public String handleError (Model model,
@RequestParam(name = "auth", required = false) String auth) {
if ("error".equals(auth)) {
model.addAttribute("error", "invalid username/password");
}
return "login";
}
}
希望这有帮助! : - )