认证原理和自定义认证
- 认证配置
- 表单认证
- 注销登录
- 前后端分离认证
- 添加验证码
自定义认证
自定义资源权限规则
- /index 公共资源
- /hello … 受保护资源 权限管理
在项目中添加如下配置就可以实现对资源权限规则设定:
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.mvcMatchers("/index").permitAll()
.anyRequest().authenticated()
.and().formLogin();
}
}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uTaqznxH-1682846578882)(SpringSecurity.assets/image-20220113050533209-2023951.png)]](https://img-blog.csdnimg.cn/0d04a1d13e1b48b8859d9658a84d8b15.png)
# 说明
- permitAll() 代表放行该资源,该资源为公共资源 无需认证和授权可以直接访问
- anyRequest().authenticated() 代表所有请求,必须认证之后才能访问
- formLogin() 代表开启表单认证
## 注意: 放行资源必须放在所有认证请求之前!
自定义登录界面
-
引入模板依赖
<!--thymeleaf--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> -
定义登录页面 controller
@Controller public class LoginController { @RequestMapping("/login.html") public String login() { return "login"; } } -
在 templates 中定义登录界面
<!DOCTYPE html> <html lang="en" xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <h1>用户登录</h1> <form method="post" th:action="@{/doLogin}"> 用户名:<input name="uname" type="text"/><br> 密码:<input name="passwd" type="password"/><br> <input type="submit" value="登录"/> </form> </body> </html>需要注意的是
- 登录表单 method 必须为
post,action 的请求路径为/doLogin - 用户名的 name 属性为
uname - 密码的 name 属性为
passwd
- 登录表单 method 必须为
-
配置 Spring Security 配置类
@Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests() .mvcMatchers("/login.html").permitAll() .mvcMatchers("/index").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login.html") .loginProcessingUrl("/doLogin") .usernameParameter("uname") .passwordParameter("passwd") .successForwardUrl("/index") //forward 跳转 注意:不会跳转到之前请求路径 //.defaultSuccessUrl("/index") //redirect 重定向 注意:如果之前请求路径,会有优先跳转之前请求路径 .failureUrl("/login.html") .and() .csrf().disable();//这里先关闭 CSRF } }- successForwardUrl 、defaultSuccessUrl 这两个方法都可以实现成功之后跳转
- successForwardUrl 默认使用
forward跳转注意:不会跳转到之前请求路径 - defaultSuccessUrl 默认使用
redirect跳转注意:如果之前请求路径,会有优先跳转之前请求路径,可以传入第二个参数进行修改
- successForwardUrl 默认使用
- successForwardUrl 、defaultSuccessUrl 这两个方法都可以实现成功之后跳转
自定义登录成功处理
有时候页面跳转并不能满足我们,特别是在前后端分离开发中就不需要成功之后跳转页面。只需要给前端返回一个 JSON 通知登录成功还是失败与否。这个时候可以通过自定义 AuthenticationSucccessHandler 实现
public interface AuthenticationSuccessHandler {
/**
* Called when a user has been successfully authenticated.
* @param request the request which caused the successful authentication
* @param response the response
* @param authentication the <tt>Authentication</tt> object which was created during
* the authentication process.
*/
void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException;
}
根据接口的描述信息,也可以得知登录成功会自动回调这个方法,进一步查看它的默认实现,你会发现successForwardUrl、defaultSuccessUrl也是由它的子类实现的
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XPoYvkqe-1682847254118)(SpringSecurity.assets/image-20220113054514897-2023963.png)]](https://img-blog.csdnimg.cn/4fef5ce5cad94910961c41243231c7d7.png)
显示登录失败信息
为了能更直观在登录页面看到异常错误信息,可以在登录页面中直接获取异常信息。Spring Security 在登录失败之后会将异常信息存储到 request 、session作用域中 key 为 SPRING_SECURITY_LAST_EXCEPTION 命名属性中,源码可以参考 SimpleUrlAuthenticationFailureHandler :

-
显示异常信息
<!DOCTYPE html> <html lang="en" xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> .... <div th:text="${SPRING_SECURITY_LAST_EXCEPTION}"></div> </body> </html> -
配置
@Configuration public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeHttpRequests() //.. .and() .formLogin() //.... //.failureUrl("/login.html") .failureForwardUrl("/login.html") .and() .csrf().disable();//这里先关闭 CSRF } }- failureUrl、failureForwardUrl 关系类似于之前提到的 successForwardUrl 、defaultSuccessUrl 方法
- failureUrl 失败以后的重定向跳转
- failureForwardUrl 失败以后的 forward 跳转
注意:因此获取 request 中异常信息,这里只能使用failureForwardUrl
- failureUrl、failureForwardUrl 关系类似于之前提到的 successForwardUrl 、defaultSuccessUrl 方法
自定义登录失败处理
和自定义登录成功处理一样,Spring Security 同样为前后端分离开发提供了登录失败的处理,这个类就是 AuthenticationFailureHandler,源码为:
public interface AuthenticationFailureHandler {
/**
* Called when an authentication attempt fails.
* @param request the request during which the authentication attempt occurred.
* @param response the response.
* @param exception the exception which was thrown to reject the authentication
* request.
*/
void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException;
}
根据接口的描述信息,也可以得知登录失败会自动回调这个方法,进一步查看它的默认实现,你会发现failureUrl、failureForwardUrl也是由它的子类实现的。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MtP8s8oO-1682849858326)(SpringSecurity.assets/image-20220113062114741.png)]](https://img-blog.csdnimg.cn/24134b26257f45a7827b5dae6faa3540.png)
- 自定义 AuthenticationFailureHandler 实现
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
Map<String, Object> result = new HashMap<String, Object>();
result.put("msg", "登录失败: "+exception.getMessage());
result.put("status", 500);
response.setContentType("application/json;charset=UTF-8");
String s = new ObjectMapper().writeValueAsString(result);
response.getWriter().println(s);
}
}
- 配置 AuthenticationFailureHandler
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
//...
.and()
.formLogin()
//..
.failureHandler(new MyAuthenticationFailureHandler())
.and()
.csrf().disable();//这里先关闭 CSRF
}
}










![[计算机图形学]高级光线传播与复杂外观建模(前瞻预习/复习回顾)](https://img-blog.csdnimg.cn/0a6053b0ea15456280f5bcba91e3ad3e.png)







