目录
学习SpringBoot使用SpringSecurity(一)_表单登录、角色认证
SpringBoot使用SpringSecurity(二)_使用注解以及更细粒度权限控制
一、自定义认证成功、失败处理
在SpringSecurityConfig配置类中
/**
* 定义具体的路径资源对应的权限
* authorizeRequests所有security全注解配置实现的开端,表示开始说明需要的权限。
* 需要的权限分两部分,第一部分是拦截的路径,第二部分访问该路径需要的权限。
* antMatchers表示拦截什么路径,permitAll任何权限都可以访问,直接放行所有。
* anyRequest()任何的请求,authenticated认证后才能访问
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 如果有允许匿名的url,填在下面
.antMatchers("/anon").permitAll()
.antMatchers("/addSysUser").permitAll()
// /admin资源需要ROLE_ADMIN角色才能访问
// .antMatchers("/admin").hasRole("ADMIN")
// /user 资源需要有ROLE_USER才能访问
// .antMatchers("/user").hasRole("USER")
//释放静态资源
.antMatchers("/js/**","/css/**","/images/*","/fonts/**","/**/*.png","/**/*.jpg").permitAll()
// 所有请求都需要认证后才能访问
.anyRequest().authenticated()
.and()
//注入 无权异常处理类
.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler)
.and()
//即 failureUrl() 指定认证失败后Url,defaultSuccessUrl() 指定认证成功后Url。
// 我们可以通过设置 successHandler() 和 failureHandler() 来实现自定义认证成功、失败处理。
// 设置登陆页
.formLogin().loginPage("/login")
// 设置登陆成功页
.defaultSuccessUrl("/").permitAll()
.failureUrl("/login")
// 自定义登陆用户名和密码参数,默认为username和password
// .usernameParameter("username")
// .passwordParameter("password")
.and()
.logout().permitAll();
// 关闭CSRF跨域
http.csrf().disable();
}
即 failureUrl() 指定认证失败后Url,defaultSuccessUrl() 指定认证成功后Url。我们可以通过设置 successHandler() 和 failureHandler() 来实现自定义认证成功、失败处理。
注意:当我们设置了这两个后,需要去除 failureUrl() 和 defaultSuccessUrl() 的设置,否则无法生效。这两套配置同时只能存在一套。
CustomAuthenticationSuccessHandler
自定义 CustomAuthenticationSuccessHandler 类来实现 AuthenticationSuccessHandler 接口,用来处理认证成功后逻辑。
/**
* @author :LiuShihao
* @date :Created in 2020/11/11 10:36 上午
* @desc : 自定义 CustomAuthenticationSuccessHandler 类来实现 AuthenticationSuccessHandler 接口,用来处理认证成功后逻辑:
*/
@Slf4j
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
log.info("登录成功,{}", authentication);
httpServletResponse.sendRedirect("/");
}
}
CustomAuthenticationFailureHandler
自定义 CustomAuthenticationFailureHandler 类来实现 AuthenticationFailureHandler 接口,用来处理认证失败后逻辑。
可以自定义认证失败逻辑。比如设置一个账号登陆失败超过三次,就锁定半小时。这里就不多叙述。
/**
* @author :LiuShihao
* @date :Created in 2020/11/11 10:38 上午
* @desc :自定义 CustomAuthenticationFailureHandler 类来实现 AuthenticationFailureHandler 接口,用来处理认证失败后逻辑
* onAuthenticationFailure()方法的第三个参数 exception 为认证失败所产生的异常,这里也是简单的返回到前台。
*/
@Slf4j
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
// @Autowired
// private ObjectMapper objectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
log.info("登陆失败");
httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
httpServletResponse.setContentType("application/json;charset=UTF-8");
//httpServletResponse.getWriter().write(objectMapper.writeValueAsString(e.getMessage()));
//认证失败重新跳转的登录页面
httpServletResponse.sendRedirect("/login");
}
}
SpringSecurityConfig配置类
- 首先将
myAuthenticationSuccessHandler
和myAuthenticationFailureHandler
注入进来 - 配置
successHandler()
和failureHandler()
- 注释
failureUrl()
和defaultSuccessUrl()
@Autowired
@Qualifier("myAuthenticationSuccessHandler")
private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
@Autowired
@Qualifier("myAuthenticationFailureHandler")
private MyAuthenticationFailureHandler myAuthenticationFailureHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// 如果有允许匿名的url,填在下面
.antMatchers("/anon").permitAll()
.antMatchers("/addSysUser").permitAll()
// /admin资源需要ROLE_ADMIN角色才能访问
// .antMatchers("/admin").hasRole("ADMIN")
// /user 资源需要有ROLE_USER才能访问
// .antMatchers("/user").hasRole("USER")
//释放静态资源
.antMatchers("/js/**","/css/**","/images/*","/fonts/**","/**/*.png","/**/*.jpg").permitAll()
// 所有请求都需要认证后才能访问
.anyRequest().authenticated()
.and()
//注入 无权异常处理类
.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler)
.and()
//即 failureUrl() 指定认证失败后Url,defaultSuccessUrl() 指定认证成功后Url。
// 我们可以通过设置 successHandler() 和 failureHandler() 来实现自定义认证成功、失败处理。
// 设置登陆页 路径
.formLogin().loginPage("/login")
.successHandler(myAuthenticationSuccessHandler)
.failureHandler(myAuthenticationFailureHandler)
.permitAll()
// 设置登陆成功 的请求路径
// .defaultSuccessUrl("/")
//设置失败 的请求路径
// .failureUrl("/login")
// 自定义登陆用户名和密码参数,默认为username和password
// .usernameParameter("username")
// .passwordParameter("password")
.and()
.logout().permitAll();
// 关闭CSRF跨域
http.csrf().disable();
}
测试
登录成功:
登陆失败则重新跳转登陆页面
二、退出登录
SpringSecurityConfig配置类
直接在 WebSecurityConfig 的 configure() 方法中,配置了
.and().logout().permitAll();
这是 Spring Security 的默认退出配置,Spring Security 在退出时候做了这样几件事:
使当前的 session 失效
清除与当前用户有关的 remember-me 记录
清空当前的 SecurityContext
重定向到登录页
Spring Security 默认的退出 Url 是 /logout,我们可以修改默认的退出 Url,例如修改为 /signout:
http.logout()
.logoutUrl("/signout");
我们也可以配置当退出时清除浏览器的 Cookie,例如清除 名为 JSESSIONID 的 cookie:
http.logout()
.logoutUrl("/signout")
.deleteCookies("JSESSIONID");
我们也可以配置退出后处理的逻辑,方便做一些别的操作:
http.logout()
.logoutUrl("/signout")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(logoutSuccessHandler);
LogoutSuccessHandler
@Slf4j
@Component
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
String username = ((User) authentication.getPrincipal()).getUsername();
log.info("退出成功,用户名:{}", username);
// 重定向到登录页
httpServletResponse.sendRedirect("/login");
}
}
退出后直接跳转登陆页面。