前后端分离
1、用户认证流程
- 登录成功后调用:AuthenticationSuccessHandler
- 登录失败后调用:AuthenticationFailureHandler
2、引入fastjson
xml
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.37</version>
</dependency>
3、认证成功的响应
3.1、成功结果处理
java
package com.neuedu.securitydemo.config;
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//获取用户身份信息
Object principal = authentication.getPrincipal();
//创建结果对象
HashMap result = new HashMap();
result.put("code", 0);
result.put("message", "登录成功");
result.put("data", principal);
//转换成json字符串
String json = JSON.toJSONString(result);
//返回响应
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
}
}
3.2、SecurityFilterChain配置
java
form.successHandler(new MyAuthenticationSuccessHandler()) //认证成功时的处理
4、认证失败响应
4.1、失败结果处理
java
package com.neuedu.securitydemo.config;
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
//获取错误信息
String localizedMessage = exception.getLocalizedMessage();
//创建结果对象
HashMap result = new HashMap();
result.put("code", -1);
result.put("message", localizedMessage);
//转换成json字符串
String json = JSON.toJSONString(result);
//返回响应
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
}
}
4.2SecurityFilterChain配置
java
form.failureHandler(new MyAuthenticationFailureHandler()) //认证失败时的处理
5、注销响应
5.1、注销结果处理
java
package com.neuedu.securitydemo.config;
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//创建结果对象
HashMap result = new HashMap();
result.put("code", 0);
result.put("message", "注销成功");
//转换成json字符串
String json = JSON.toJSONString(result);
//返回响应
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
}
}
5.2、SecurityFilterChain配置
java
http.logout(logout -> {
logout.logoutSuccessHandler(new MyLogoutSuccessHandler()); //注销成功时的处理
});
6、请求未认证的接口
6.1、实现AuthenticationEntryPoint接口
Servlet Authentication Architecture :: Spring Security
当访问一个需要认证之后才能访问的接口的时候,Spring Security会使用AuthenticationEntryPoint
将用户请求跳转到登录页面,要求用户提供登录凭证。
这里我们也希望系统返回json结果
,因此我们定义类实现AuthenticationEntryPoint接口
java
package com.neuedu.securitydemo.config;
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
//获取错误信息
//String localizedMessage = authException.getLocalizedMessage();
//创建结果对象
HashMap result = new HashMap();
result.put("code", -1);
result.put("message", "需要登录");
//转换成json字符串
String json = JSON.toJSONString(result);
//返回响应
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
}
}
6.2、SecurityFilterChain配置
java
//错误处理
http.exceptionHandling(exception -> {
exception.authenticationEntryPoint(new MyAuthenticationEntryPoint());//请求未认证的接口
});
7、跨域
跨域全称是跨域资源共享(Cross-Origin Resources Sharing,CORS),它是浏览器的保护机制,只允许网页请求统一域名下的服务,同一域名指=>协议、域名、端口号都要保持一致,如果有一项不同,那么就是跨域请求。在前后端分离的项目中,需要解决跨域的问题。
在SpringSecurity中解决跨域很简单,在配置文件中添加如下配置即可
java
//跨域
http.cors(withDefaults());