Spring Security 自定义授权登录成功后自定义方法

在使用 Spring Security 做权限管理的时候,授权登录成功后,一般是跳转到首页。但是我们想再授权成功一瞬间做一些额外的操作,比如记录日志,添加 Session 等。

具体做法如下

创建 SecurityConfig 类,继承 WebSecurityConfigurerAdapter

重写 protected void configure(HttpSecurity http)  方法

在里面添加如下代码

  1. .successHandler(new AuthenticationSuccessHandler() {
  2.     @Override
  3.     public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
  4.         Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
  5.         if (principal != null && principal instanceof UserDetails) {
  6.             UserDetails user = (UserDetails) principal;
  7.             //1、添加 Session
  8.             httpServletRequest.getSession().setAttribute("userDetail", user);
  9.             //2、写入日志
  10.             logger.info("【用户已登录】" + user.getUsername());
  11.             //3、写入数据库login_record表
  12.             LoginRecord loginRecord = new LoginRecord();
  13.             loginRecord.setLoginIp(IPUtil.getIpAddr(httpServletRequest));
  14.             loginRecord.setLoginTime(System.currentTimeMillis());
  15.             loginRecord.setUser((User) user);
  16.             loginRecordRepository.save(loginRecord);
  17.             //4、页面跳转到首页
  18.             httpServletResponse.sendRedirect(ctx);//即 /forum
  19.         }
  20.     }
  21. })

第 7 行-第 19 行是自定义操作

 

完整代码如下

  1. package com.liuyanzhao.forum.config;
  2. import com.liuyanzhao.forum.entity.LoginRecord;
  3. import com.liuyanzhao.forum.entity.User;
  4. import com.liuyanzhao.forum.repository.LoginRecordRepository;
  5. import com.liuyanzhao.forum.service.impl.CustomUserService;
  6. import com.liuyanzhao.forum.util.IPUtil;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.beans.factory.annotation.Value;
  11. import org.springframework.context.annotation.Bean;
  12. import org.springframework.security.authentication.AuthenticationManager;
  13. import org.springframework.security.authentication.AuthenticationProvider;
  14. import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
  15. import org.springframework.security.config.BeanIds;
  16. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  17. import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
  18. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  19. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  20. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  21. import org.springframework.security.core.Authentication;
  22. import org.springframework.security.core.context.SecurityContextHolder;
  23. import org.springframework.security.core.userdetails.UserDetails;
  24. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  25. import org.springframework.security.crypto.password.PasswordEncoder;
  26. import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
  27. import javax.servlet.ServletException;
  28. import javax.servlet.http.HttpServletRequest;
  29. import javax.servlet.http.HttpServletResponse;
  30. import java.io.IOException;
  31. /**
  32.  * 安全配置类
  33.  *
  34.  * @author 言曌
  35.  * @date 2018/1/23 上午11:37
  36.  */
  37. @EnableWebSecurity
  38. @EnableGlobalMethodSecurity(prePostEnabled = true// 启用方法安全设置
  39. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  40.     @Value("${server.servlet.context-path}")
  41.     public String ctx;
  42.     private static final String KEY = "liuyanzhao.com";
  43.     private final Logger logger = LoggerFactory.getLogger(this.getClass());
  44.     @Autowired
  45.     private LoginRecordRepository loginRecordRepository;
  46.     /**
  47.      * 自定义UserDetailsService,从数据库中读取用户信息
  48.      *
  49.      * @return
  50.      */
  51.     @Bean
  52.     public CustomUserService customUserDetailsService() {
  53.         return new CustomUserService();
  54.     }
  55.     @Bean
  56.     public PasswordEncoder passwordEncoder() {
  57.         return new BCryptPasswordEncoder();// 使用 BCrypt 加密
  58.     }
  59.     @Bean
  60.     public AuthenticationProvider authenticationProvider() {
  61.         DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
  62.         authenticationProvider.setUserDetailsService(customUserDetailsService());
  63.         authenticationProvider.setPasswordEncoder(passwordEncoder()); // 设置密码加密方式
  64.         return authenticationProvider;
  65.     }
  66.     @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
  67.     @Override
  68.     public AuthenticationManager authenticationManagerBean() throws Exception {
  69.         return super.authenticationManagerBean();
  70.     }
  71.     /**
  72.      * 自定义配置
  73.      */
  74.     @Override
  75.     protected void configure(HttpSecurity http) throws Exception {
  76.         http.authorizeRequests().antMatchers("/css/**""/js/**""/fonts/**""/index").permitAll() // 都可以访问
  77.                 .antMatchers("/h2-console/**").permitAll() // 都可以访问
  78.                 .antMatchers("/login").permitAll() // 都可以访问
  79.                 .antMatchers("/admin/**").hasRole("ADMIN"// 需要相应的角色才能访问
  80.                 .and()
  81.                 .formLogin()   //基于 Form 表单登录验证
  82.                 .loginPage("/login").failureUrl("/login?error=true"// 自定义登录界面
  83.                 .successHandler(new AuthenticationSuccessHandler() {
  84.                     @Override
  85.                     public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
  86.                         Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
  87.                         if (principal != null && principal instanceof UserDetails) {
  88.                             UserDetails user = (UserDetails) principal;
  89.                             //1、添加 Session
  90.                             httpServletRequest.getSession().setAttribute("userDetail", user);
  91.                             //2、写入日志
  92.                             logger.info("【用户已登录】" + user.getUsername());
  93.                             //3、写入数据库login_record表
  94.                             LoginRecord loginRecord = new LoginRecord();
  95.                             loginRecord.setLoginIp(IPUtil.getIpAddr(httpServletRequest));
  96.                             loginRecord.setLoginTime(System.currentTimeMillis());
  97.                             loginRecord.setUser((User) user);
  98.                             loginRecordRepository.save(loginRecord);
  99.                             //4、页面跳转到首页
  100.                             httpServletResponse.sendRedirect(ctx);//即 /forum
  101.                         }
  102.                     }
  103.                 })
  104. //                .defaultSuccessUrl("/")//登陆成功页面,需要去掉,否则不会执行上面的方法
  105.                 .and().rememberMe().key(KEY) // 启用 remember me
  106.                 .and().exceptionHandling().accessDeniedPage("/403");  // 处理异常,拒绝访问就重定向到 403 页面
  107.         http.csrf().ignoringAntMatchers("/h2-console/**"); // 禁用 H2 控制台的 CSRF 防护
  108.         http.csrf().ignoringAntMatchers("/ajax/**"); // 禁用 H2 控制台的 CSRF 防护
  109.         http.headers().frameOptions().sameOrigin(); // 允许来自同一来源的H2 控制台的请求
  110.     }
  111.     /**
  112.      * 认证信息管理
  113.      *
  114.      * @param auth
  115.      * @throws Exception
  116.      */
  117.     @Autowired
  118.     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
  119.         auth.userDetailsService(customUserDetailsService());
  120.         auth.authenticationProvider(authenticationProvider());
  121.     }
  122. }

 

其他代码不是本文的重点,这里省略。

 

本文地址:https://liuyanzhao.com/7898.html

  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
言曌

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: