本文将介绍如何对 Spring Security 进行改造,以适应使用 JSON 交互的前后端分离开发模式。
一、JSON 交互
在现如今的 Web 开发中,前后端分离的开发模式是绝对的主流。在这种开发模式下,前后端将独立,后端只提供接口,接收请求并返回数据。
此时,Spring Security 相对 “老旧” 的设计就会显得过时,比如:
- 在未登录、无权限时,返回登录页面要求登录(而非返回 JSON,并在 JSON 中指示权限不足)
- 当登录成功后,跳转至首页(而非返回登录成功的结果)
因此,对 Spring Security 做 JSON 改造是十分有必要的。
二、配置
1. 登录成功处理器
(1) 编写
编写类,继承 AuthenticationSuccessHandler,在方法中返回 JSON 即可。
1 2 3 4 5 6 7 8
| @Component public class LoginSuccessHandler implements AuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { PrintWriter writer = response.getWriter(); writer.println("Success Login"); } }
|
(2) 配置
在配置类中配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired LoginSuccessHandler loginSuccessHandler;
@Override protected void configure(HttpSecurity http) throws Exception { http .formLogin() .successHandler(loginSuccessHandler) } }
|
2. 登录失败处理器
(1) 编写
编写类,继承 AuthenticationFailureHandler,在方法中返回 JSON 即可。
1 2 3 4 5 6 7 8
| @Component public class LoginFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { PrintWriter writer = response.getWriter(); writer.println("Failure Login"); } }
|
(2) 配置
在配置类中配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired LoginFailureHandler loginFailureHandler;
@Override protected void configure(HttpSecurity http) throws Exception { http .formLogin() .failureHandler(loginFailureHandler) } }
|
3. 登出处理器
(1) 编写
编写类,继承 LogoutSuccessHandler,在方法中返回 JSON 即可。
1 2 3 4 5 6 7 8
| @Component public class LogoutHandler implements LogoutSuccessHandler { @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { PrintWriter writer = response.getWriter(); writer.println("Success Logout"); } }
|
(2) 配置
在配置类中配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired LogoutHandler logoutHandler;
@Override protected void configure(HttpSecurity http) throws Exception { http .logout() .logoutSuccessHandler(logoutHandler) } }
|
4. 未登录处理器
(1) 编写
编写类,继承 AuthenticationEntryPoint,在方法中返回 JSON 即可。
1 2 3 4 5 6 7 8
| @Component public class AuthenticationEntryPoint implements org.springframework.security.web.AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { PrintWriter writer = response.getWriter(); writer.println("Please Login"); } }
|
(2) 配置
在配置类中配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired AuthenticationEntryPoint authenticationEntryPoint;
@Override protected void configure(HttpSecurity http) throws Exception { http .exceptionHandling() .authenticationEntryPoint(authenticationEntryPoint) } }
|
5. 无权限处理器
(1) 编写
编写类,继承 LogoutSuccessHandler,在方法中返回 JSON 即可。
1 2 3 4 5 6 7 8
| @Component public class AccessDeniedHandler implements org.springframework.security.web.access.AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { PrintWriter writer = response.getWriter(); writer.println("Access Denied"); } }
|
(2) 配置
在配置类中配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired AccessDeniedHandler accessDeniedHandler;
@Override protected void configure(HttpSecurity http) throws Exception { http .exceptionHandling() .accessDeniedHandler(accessDeniedHandler) } }
|
参考