源码简介
当进行登录时会执行 UsernamePasswordAuthenticationFilter
过滤器。
//表单提交
http.formLogin()
//自定义登录页面
.loginPage("/login.html")
//当发现/login时认为是登录,必须和表单提交的地址一样。去执行UserServiceImpl
.loginProcessingUrl("/login")
//登录成功后跳转页面,POST请求
.successForwardUrl("/toMain")
//登录失败后跳转页面,POST请求
.failureForwardUrl("/toError")
.usernameParameter("myusername")
.passwordParameter("mypassword");
form action="/login" method="post">
用户名:<input type="text" name="myusername" /><br/>
密码:<input type="password" name="mypassword" /><br/>
<input type="submit" value="登录" />
</form>
源码分析
使用successForwardUrl()
时表示成功后转发请求到地址。内部是通过 successHandler()
方法进行控制成功后交 给哪个类进行处理
ForwardAuthenticationSuccessHandler
内部就是最简单的请求转发。
由于是请求转发,当遇到需要跳转到站外或 在前后端分离的项目中就无法使用了。
当需要控制登录成功后去做一些事情时,可以进行自定义认证成功控制器。
自定义类
新建类 com.xiaobai.handler.MyAuthenticationSuccessHandler 编写如下:
package com.example.spring.config;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 身份验证成功处理程序
*
* @author 爪哇小白2021
* @date 2022/07/04
*/
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private String url;
public MyAuthenticationSuccessHandler(String url) {
this.url = url;
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//Principal 主体,存放了登录用户的信息
User user = (User) authentication.getPrincipal();
System.out.println(user.getUsername());
//输出null
System.out.println(user.getPassword());
System.out.println(user.getAuthorities());
response.sendRedirect(url);
}
}
使用 successHandler()
方法设置成功后交给哪个对象进行处理
//表单提交
http.formLogin()
//自定义登录页面
.loginPage("/login.html")
//当发现/login时认为是登录,必须和表单提交的地址一样。去执行UserServiceImpl
.loginProcessingUrl("/login")
//登录成功后跳转页面,POST请求
// .successForwardUrl("/toMain")
//和successForwardUrl不能共存
.successHandler(new MyAuthenticationSuccessHandler("http://www.baidu.com"))
//登录失败后跳转页面,POST请求
.failureForwardUrl("/toError")
.usernameParameter("myusername")
.passwordParameter("mypassword");
源码分析 failureForwardUrl()
内部调用的是 failureHandler()
方法
ForwardAuthenticationFailureHandler
中也是一个请求转发,并在request
作用域中设置 SPRING_SECURITY_LAST_EXCEPTION
的 key,内容为异常对象。
新建控制器
新建 com.xiaobai.handler.MyForwardAuthenticationFailureHandler 实现AuthenticationFailureHandler。在方法中 添加重定向语句
package com.example.spring.config;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 转发处理身份验证失败
*
* @author 爪哇小白2021
* @date 2022/07/04
*/
public class MyForwardAuthenticationFailureHandler implements AuthenticationFailureHandler {
private String url;
public MyForwardAuthenticationFailureHandler(String url) {
this.url = url;
}
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.sendRedirect(url);
}
}
修改配置类中表单登录部分。
设置失败时交给失败处理器进行操作。 failureForwardUrl
和 failureHandler
不可 共存。
//表单提交
http.formLogin()
//自定义登录页面
.loginPage("/login.html")
//当发现/login时认为是登录,必须和表单提交的地址一样。去执行UserServiceImpl
.loginProcessingUrl("/login")
//登录成功后跳转页面,POST请求
// .successForwardUrl("/toMain")
//和successForwardUrl不能共存
.successHandler(new MyAuthenticationSuccessHandler("http://www.baidu.com"))
//登录失败后跳转页面,POST请求
// .failureForwardUrl("/toError")
.failureHandler(new MyForwardAuthenticationFailureHandler("/error.html"))
.usernameParameter("myusername")
.passwordParameter("mypassword");
败后跳转页面,POST请求
// .failureForwardUrl("/toError")
.failureHandler(new MyForwardAuthenticationFailureHandler("/error.html"))
.usernameParameter("myusername")
.passwordParameter("mypassword");