1.失败跳转
表单处理中成功会跳转到一个地址,失败也可以跳转到一个地址中
1.1 编写页面
在 src/main/resources/static 下新建 fail.html 并编写如下内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
操作失败,请重新登录. <a href="/login.html">跳转</a>
</body>
</html>
1.2 修改表单配置
在配置方法中表单认证部分添加 failureForwardUrl()方法,表示登录失败跳转的 url。此处依然是 POST 请求,所以跳转到可以接收 POST 请求的控制器/fail 中
// 表单认证
http.formLogin()
.loginProcessingUrl("/login") //当发现/login 时认为是登录,需要执行 UserDetailsServiceImpl
.successForwardUrl("/toMain") //此处是 post 请求
.failureForwardUrl("/fail") //登录失败跳转地址
.loginPage("/login.html");
1.3 添加控制器方法
在控制器类中添加控制器方法,方法映射路径/fail。此处要注意:由于是 POST 请求访问/fail。所以如果返回值直接转发到 fail.html 中,及时有效果,控制台也会报警告,提示 fail.html 不支持 POST 访问方式
@PostMapping("/fail")
public String fail(){
return "redirect:/fail.html";
}
1.4 设置 fail.html 不需要认证
认证失败跳转到 fail.html 页面中,所以必须配置 fail.html 不需要被认证。需要修改配置类中内容
// url 拦截
http.authorizeRequests()
.antMatchers("/login.html").permitAll() //login.html 不需要被认证
.antMatchers("/fail.html").permitAll() //fail.html 不需要被认证
.anyRequest().authenticated();//所有的请求都必须被认证。必须登录后才能访问
2.设置请求账户和密码的参数名
2.1 源码简介
当进行登录时会执行 UsernamePasswordAuthenticationFilter 过滤器
usernamePasrameter:账户参数名
passwordParameter:密码参数名
postOnly=true:默认情况下只允许 POST 请求
2.2 修改配置
// 表单认证
http.formLogin()
.loginProcessingUrl("/login") //当发现/login 时认为是登录,需要执行 UserDetailsServiceImpl
.successForwardUrl("/toMain") //此处是 post 请求
.failureForwardUrl("/fail") //登录失败跳转地址
.loginPage("/login.html")
.usernameParameter("myusername")
.passwordParameter("mypassword");
2.3 修改页面
修改 login.html
<form action = "/login" method="post">
用户名:<input type="text" name="myusername"/><br/>
密码:<input type="password" name="mypassword"/><br/>
<input type="submit" value="登录"/>
</form>
3.自定义登录成功处理器
3.1 源码分析
使用 successForwardUrl()时表示成功后转发请求到地址。内部是 通过 successHandler()方法进行控制成功后交给哪个类进行处
ForwardAuthenticationSuccessHandler 内部就是最简单的请求转发。由于是请求转发,当遇到需要跳转到站外或在前后端分离的项目中就无法使用了
当需要控制登录成功后去做一些事情时,可以进行自定义认证成功控制器
3.2 代码实现
3.2.1 自定义类
新建类 com.dqcgm.handler.MyAuthenticationSuccessHandler 编写如下:
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
//Principal 主体,存放了登录用户的信息
User user = (User)authentication.getPrincipal();
System.out.println(user.getUsername());
System.out.println(user.getPassword());//密码输出为 null
System.out.println(user.getAuthorities());
//重定向到百度。这只是一个示例,具体需要看项目业务需求
httpServletResponse.sendRedirect("http://www.baidu.com");
}
}
3.2.2 修改配置项
使用 successHandler()方法设置成功后交给哪个对象进行处理
// 表单认证
http.formLogin()
.loginProcessingUrl("/login") //当发现/login 时认为是登录,需要执行 UserDetailsServiceImpl
.successHandler(new MyAuthenticationSuccessHandler())
//.successForwardUrl("/toMain") //此处是 post 请求
.failureForwardUrl("/fail") //登录失败跳转地址
.loginPage("/login.html");
4.自定义登录失败处理器
4.1 源码分析
failureForwardUrl()内部调用的是 failureHandler()方法
ForwardAuthenticationFailureHandler 中也是一个请求转发,并在 request 作用域中设置 SPRING_SECURITY_LAST_EXCEPTION 的 key,内容为异常对象
4.2 代码实现
4.2.1 新建控制器
新建 com.dqcgm.handler.MyForwardAuthenticationFailureHandler 实现 AuthenticationFailureHandler。在方法中添加重定向语句
public class MyForwardAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.sendRedirect("/fail.html");
}
}
4.2.2 修改配置类
修改配置类中表单登录部分。设置失败时交给失败处理器进行操作。failureForwardUrl 和 failureHandler 不可共存
// 表单认证
http.formLogin()
.loginProcessingUrl("/login") //当发现/login 时认为是登录,需 要执行 UserDetailsServiceImpl
.successHandler(new MyAuthenticationSuccessHandler())
//.successForwardUrl("/toMain") //此处是 post 请求
.failureHandler(new MyForwardAuthenticationFailureHandler())
.failureForwardUrl("/fail") //登录失败跳转地址
.loginPage("/login.html");