标签:信息 handler val 注意 null lin out 源码 功能
在整合springsecurity时遇到好几个问题,自动配置登录,下线,注销用户的操作,数据基于mybatis,模版引擎用的thymeleaf+bootstrap。
一、认证时密码的加密(passwordEncoder)原理如下
//认证 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()).passwordEncoder(new PasswordEncoder() { @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { //匹配 =================将用户表单登录的密码和encodedPasswor(这个值是从MyUserDetailService那边封装过来的))对比================= return encodedPassword.equals(encode(rawPassword)); } @Override public String encode(CharSequence rawPassword) { return MD5Util.encode((String) rawPassword); } }); }
@Service public class MyUserDetailService implements UserDetailsService { @Autowired UserService userService; @Autowired private SessionRegistry sessionRegistry; @Override public UserDetails loadUserByUsername(String username) { if (username==null || username.equals("")) { throw new UsernameNotFoundException("用户名不存在"); } Sys_User user=userService.getUserByName(username); //获得所有登录用户的信息 List<Object> list =sessionRegistry.getAllPrincipals(); for (Object object : list) { if (((User)object).getUsername().equals(user.getUsername())) { throw new SessionAuthenticationException("当前用户已经在线,登录失败"); } System.out.println("getAllPrincipals的遍历"+((User)object).getUsername()); } //得到当前登录用户的信息 List<SimpleGrantedAuthority> authorities = new ArrayList<>(); for (Role role : user.getRoles()) { //将得到的角色封装 在后面页面认证成功后会用到 authorities.add(new SimpleGrantedAuthority(role.getRolename())); System.out.println("拥有的角色:"+role.getRolename()); } return new User(user.getUsername(), user.getPassword(), authorities); } }
二、授权时session的管理的配置(configure(HttpSecurity http)中)
//开启自动配置的注销功能。 http.logout().permitAll();//logoutUrl("/logout").logoutSuccessUrl("/");//表示注销成功以后来到首页 http //session管理 .sessionManagement() .maximumSessions(1).maxSessionsPreventsLogin(true) .sessionRegistry(getSessionRegistry());
http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true)
在实测后发现设定上限后 最大登录次数为设定数目 +1 比如设定数2 则最大访问数目为3 第四次开始报错
由此 如果我们用这个配置去指定用户单登录是不行的
http.sessionManagement().sessionFixation().migrateSession()spring security防止篡改session
三、自定义注销,下线的实现(重点)
if (invalidateHttpSession) {//部分源码 HttpSession session = request.getSession(false); if (session != null) { logger.debug("Invalidating session: " + session.getId()); session.invalidate(); } }
@RequestMapping("/logout") public String logout(HttpServletRequest request,HttpServletResponse response){ /** * 第一种方式 单纯的离线 并未注销用户 即sessionID还在 * */ //获得注销用户的信息 Authentication auth=SecurityContextHolder.getContext().getAuthentication(); if (auth != null){ //设置为离线状态 new SecurityContextLogoutHandler().logout(request, response, auth); } return "redirect:/login"; }
@RequestMapping("/logout") public String logout2() { /** * 第二种 将获取到登录用户信息后将该用户sessionID置为无效 然后再从sessionRegistry中移除 * 这种方式可以彻底注销用户登录状态 */ List<Object> pList=sessionRegistry.getAllPrincipals(); List<SessionInformation> sessionsInfo = null; for (Object principle : pList) { sessionsInfo=sessionRegistry.getAllSessions(principle, false); } System.out.println("sesssion个数"+sessionsInfo.size()); for (SessionInformation sessionInformation : sessionsInfo) { //获取当前sessionid System.out.println("SESSIONID:"+sessionInformation.getSessionId()); sessionInformation.expireNow();//将session置为无效然后在下一步移除 sessionRegistry.removeSessionInformation(sessionInformation.getSessionId()); } return "redirect:/login"; }
四、源码
源码实现私信我
springboot整合springsecurity遇到的问题
标签:信息 handler val 注意 null lin out 源码 功能
原文地址:https://www.cnblogs.com/wangsr-suc/p/9380147.html