阅前提示
此文章基于Spring Security 6.0
Spring Security中的登出配置
由于登出没什么好讲的,那就直接上代码
@Configuration
@EnableWebSecurity
public class LogoutSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers("/**").hasRole("USER").and().formLogin()
.and()
// sample logout customization
.logout().deleteCookies("JSESSIONID").invalidateHttpSession(false)
.logoutUrl("/custom-logout").logoutSuccessUrl("/logout-success");
return http.build();
}
}
在上面的配置中,当URL “/custom-logout"被调用后,删除名为JSESSIONID的cookie,清除SecurityContextHolder,但不会使httpSession无效,然后重定向到”/logout-success"中
对于不使用session与cookie的项目,可以这样配置
@Configuration
@EnableWebSecurity
public class LogoutSecurityConfig {
@Autowired
private SecurityLogoutSuccessHandler logoutSuccessHandler;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().requestMatchers("/**").hasRole("USER").and().formLogin()
.and()
.logout()
.logoutUrl("/custom-logout")
.logoutSuccessHandler(logoutSuccessHandler);
return http.build();
}
}
@Component
public class SecurityLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
SecurityContextHolder.clearContext();
//TODO clear the data of login user
response.getWriter().println("{success:true}");
}
}
忘记了默认有没有清空SecurityContextHolder了,反正再清空一遍也不要紧,就写着好了。把记录登录用户的数据(redis或者内存什么的)删除
Spring Security中异常配置(未认证,未授权管理)
@Configuration
@EnableWebSecurity
public class ExceptionHandlingSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests((authorizeRequests) ->
authorizeRequests
.requestMatchers("/**").hasRole("USER")
)
// sample exception handling customization
.exceptionHandling((exceptionHandling) ->
exceptionHandling
.accessDeniedPage("/errors/access-denied")
);
return http.build();
}
}
上面的配置是,当遇到403 拒绝时,重定向到"/errors/access-denied"页面。
@Configuration
@EnableWebSecurity
public class ExceptionHandlingSecurityConfig {
//认证入口处理类(未认证情况下访问需认证访问资源)
@Autowired
private SecurityAuthenticationEntryPoint securityAuthenticationEntryPoint;
//没有权限处理类
@Autowired
private SecurityAccessDeniedHandler securityAccessDeniedHandler;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests((authorizeRequests) ->
authorizeRequests
.requestMatchers("/**").hasRole("USER")
)
// sample exception handling customization
.exceptionHandling(exception -> {
exception
.authenticationEntryPoint(securityAuthenticationEntryPoint)
.accessDeniedHandler(securityAccessDeniedHandler);
});
return http.build();
}
}
@Component
public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.getWriter().println("{success:false,code:401,message:" + authException.getMessage() + "}");
}
}
@Component
public class SecurityAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.getWriter().println("{success:false,code:403,message:" + accessDeniedException.getMessage() + "}");
}
}
对于前后端分离项目来说,页面是从前端项目获取的,不需要后端提供,后端只要提供数据就行了。自定义401与403处理类,只返回数据