SpringSecurity6从入门到实战之登录后操作
上次已经了解了如何进行自定义登录页面,这次主要是详细讲解登录成功,登录之后的跳转以及包括退出登录等一系列操作.让我们来看看SpringSecurity需要如何进行配置
登录之后的跳转
定义 Spring Security 配置类
@Configuration
@EnableWebSecurity
public class MySecurityConfig {
// 自定义表单认证
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.requestMatchers("/test").permitAll() // 放行该资源
.requestMatchers("/login.html").permitAll() // 放行该资源
.anyRequest().authenticated() // 其它请求 必须先认证通过后 才能访问
.and().formLogin() // 开启表单认证
.loginPage("/login.html") // 默认登录页
.loginProcessingUrl("/doLogin") // 处理登录请求的url
.usernameParameter("uname") // 用户名文件框的名称
.passwordParameter("upass") // 密码框的名称
// 登录成功 跳转
.successForwardUrl("/test") //forward转发 跳转 不会跳转到之前请求路径
//.defaultSuccessUrl("/test") //redirect 重定向 如果之前有请求路径,会优先跳转之前请求的路径
.and().csrf().disable(); // 关闭 CSRF
;
return http.build();
}
}
这里就不一一进行测试展示了
成功后的跳转有两个方法 successForwardUrl 、defaultSuccessUrl
- successForwardUrl forward 跳转 (注意:不会跳转到之前请求路径)
- defaultSuccessUrl redirect 跳转 (注意:如果之前请求路径,会有优先跳转之前请求路径,可以通过第二个参数进行修改)
.defaultSuccessUrl(“/test”, true) // redirect 跳转,且直接跳到 /test
登录成功之后返回JSON
在前后端分离开发中成功之后不需要跳转到页面,只需要给返回一个 JSON 通知登录成功还是失败即可。这个时候可以通过自定义
AuthenticationSucccessHandler
实现
自定义 AuthenticationSuccessHandler 的实现类
创建MyAuthenticationSuccessHandler实现AuthenticationSuccessHandler
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
Map<String, Object> result = new HashMap<String, Object>();
result.put("msg", "登录成功");
result.put("status", 200);
response.setContentType("application/json;charset=UTF-8");
String s = new ObjectMapper().writeValueAsString(result);
response.getWriter().println(s);
}
}
定义 Spring Security 配置类
@Configuration
@EnableWebSecurity
public class MySecurityConfig {
// 自定义表单认证
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
// ....
.and().formLogin() // 开启表单认证
// ....
// 登录成功 JSON处理(将我们自定义 AuthenticationSuccessHandler 的实现类作为参数传入successHandler()即可)
.successHandler(new MyAuthenticationSuccessHandler())
.and().csrf().disable(); //关闭 CSRF
;
return http.build();
}
}
登录失败后的跳转
定义 Spring Security 配置类
@Configuration
@EnableWebSecurity
public class MySecurityConfig {
// 自定义表单认证
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
// ....
.and().formLogin() // 开启表单认证
// ....
// 登录失败 跳转
.failureForwardUrl("/login.html") // 登录失败 forward跳转
//.failureUrl("/login.html") // 登录失败 redirect跳转
.and().csrf().disable(); // 关闭 CSRF
;
return http.build();
}
}
# failureForwardUrl、failureUrl 方法类似于登录成功跳转时的 successForwardUrl 、defaultSuccessUrl 方法:
- failureForwardUrl 登录失败后的 forward 跳转
- failureUrl 登录失败后的 redirect 跳转
登录失败之后返回JSON
自定义 AuthenticationFailureHandler
的实现类(这里与成功实现的类不一样注意!)
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
HashMap<String, Object> result = new HashMap<>();
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);
}
}
定义 Spring Security 配置类
@Configuration
@EnableWebSecurity
public class MySecurityConfig {
// 自定义表单认证
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
// ....
.and().formLogin() // 开启表单认证
// ....
// 登录失败 JSON处理
.failureHandler(new MyAuthenticationFailureHandler())
.and().csrf().disable(); // 关闭 CSRF
;
return http.build();
}
}
退出登录之后的跳转
这里还是和上面的登录成功失败一样的流程只需要进行配置即可
定义 Spring Security 配置类
@Configuration
@EnableWebSecurity
public class MySecurityConfig {
// 自定义表单认证
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
// ....
.and().formLogin() // 开启表单认证
// ....
// 退出
.and()
.logout()
.logoutUrl("/logout") // 默认 /logout
.invalidateHttpSession(true) // 默认true 让当前session失效
.clearAuthentication(true) // 默认true 清除当前认证标记
.logoutSuccessUrl("/login.html") // 退出成功后 跳转到/login.html
.and().csrf().disable();
;
return http.build();
}
}
模拟主页,退出登录按钮
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页</title>
</head>
<body>
<h3>欢迎来到主页</h3>
当前用户:xxx <br/>
<a href="/logout">退出</a>
</body>
</html>
定义主页controller
IndexController
@Controller
public class IndexController {
@RequestMapping("/index.html")
public String index() {
return "index";
}
}
退出登录之后返回JSON
自定义 LogoutSuccessHandler 的实现类
也是跟上面一样的流程需要创建一个自定义 LogoutSuccessHandler 的实现类,然后进行配置
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
HashMap<String, Object> result = new HashMap<>();
result.put("msg", "退出成功!" + authentication);
result.put("status", 200);
response.setContentType("application/json; charset=UTF-8");
String s = new ObjectMapper().writeValueAsString(result);
response.getWriter().println(s);
}
}
定义 Spring Security 配置类
@Configuration
@EnableWebSecurity
public class MySecurityConfig {
// 自定义表单认证
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
// ....
.and().formLogin() // 开启表单认证
// ....
// 退出
.and()
.logout()
.logoutUrl("/logout") // 默认 /logout
.invalidateHttpSession(true) // 默认true 让当前session失效
.clearAuthentication(true) // 默认true 清除当前认证标记
.logoutSuccessHandler(new MyLogoutSuccessHandler())
.and().csrf().disable();
;
return http.build();
}
}