本文主要是介绍Spring Security中用户名和密码的验证完整流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定...
首先创建了一个UsernamePasswordAuthenticationTChina编程oken
对象,这是Spring Security中用于表示基于用户名和密码的认证请求的一个类。这个对象被初始化时,接收了两个参数:username(用户名)和password(密码)。这两个参数代表了用户尝试登录时提供的凭证。
接下来,通过调用authenticationManager的authenticate方法,并传入前面创建的authenticationToken对象,来执行认证过程。authenticationManager
是Spring Security中的一个核心接口,它负责处理认证请求。在调用authenticate方法时,Spring Security会基于配置的安全策略(比如从数据库、LDAP服务器或其他认证源中检索用户信息,并验证提供的密码是否正确)来验证用户提供的凭证是否有效
如果认证成功,authenticate
方法会返回一个填充了用户权限等详细信息的Authentication对象。这个对象代表了认证成功后的用户会话,包含了用户的身份信息、权限、是否已记住我(remember-me)等详细信息。
如果认证失败,authenticate方法会抛出一个AuthenticationException异常,这通常意味着提供的用户名或密码不正确,或者用户账户处于锁定、禁用等状态。
/** * 登录验证 * * @param username 用户名 * @param password 密码 * @param code 验证码 * @param uuid 唯一标识 * @return 结果 */ public String login(String username, String password, String code, String uuid) { // 验证码校验 validateCaptcha(username, code, uuid); // 登录前置校验 loginPreCheck(username, password); // 用户验证 Authentication authentication = null; try { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); AuthenticationContextHolder.setContext(authenticationToken); // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername authentication = authenticationManager.authenticate(authenticationToken); } catch (Exception e) { if (e instanceof BadCredentialsException) { AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); throw new UserPasswordNotMatchException(); } else { AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); throw new ServiceException(e.getMessage()); } } finally { //清理认证上下文,确保线程上下文中的认证信息被清除,避免潜在的内存泄漏或安全问题 AuthenticationContextHolder.clearContext(); } AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); //从认证成功的Authentication对象中获取Principal,并将其强制转换为LoginUser对象。LoginUser是一个自定义类,通常包含用户的基本信息和权限信息 LoginUser loginUser = (LoginUser) authentication.getPrincipal(); //调用recordLoginInfo方法记录用户的登录信息,例如登录时间、IP地址等 recordLoginInfo(loginUser.getUserId()); // 生成token,为用户生成一个Token,并返回该Token。Token通常用于后续的用户身份验证和授权 return tokenService.createToken(loginUser); }
验证码校验方法
/** * 校验验证码 * * @param username 用户名 * @param code 验证码 * @param uuid 唯一标识 * @return 结果 */ public void validateCaptcha(String username, String code, String uuid) { boolean captchaEnabled = configService.selectCaptchaEnabled(); if (captchaEnabled) { String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); String captcha = RedisCache.getCacheObject(verifyKey); if (captcha == null) { AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.mes编程China编程sage("user.jcaptchaandroid.expire"))); throw new CaptchaExpireException(); } redisCache.deleteObject(verifyKey); if (!code.equalsIgnoreCase(captcha)) { AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); throw new CaptchaException(); } } }
用户名和密码校验代码
/** * 登录前置校验 * @param username 用户名 * @param password 用户密码 */ public void loginPreCheck(String username, String password) { // 用户名或密码为空 错误 if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); throw new UserNotExistsException(); } China编程 // 密码如果不在指定范围内 错误 if (password.length() < UserConstants.PASSWORD_MIN_LENGTH || password.length() > UserConstants.PASSWORD_MAX_LENGTH) { AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); throw new UserPasswordNotMatchException(); } // 用户名不在指定范围内 错误 if (username.length() < UserConstants.USERNAME_MIN_LENGTH || username.length() > UserConstants.USERNAME_MAX_LENGTH) { AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); throw new UserPasswordNotMatchException(); } // IP黑名单校验 String blackStr = configService.selectConfigByKey("sys.login.blackIPList"); if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked"))); throw new BlackListException(); } }
记录登录信息代码
/** * 记录登录信息 * * @param userId 用户ID */ public void recordLoginInfo(Long userId) { SysUser sysUser = new SysUser(); sysUser.setUserId(userId); sysUser.setLoginIp(IpUtils.getIpAddr()); sysUser.setLoginDate(DateUtils.getNowDate()); userService.updateUserProfile(sysUser); }
UserDetailsServichttp://www.chinasem.cneImpl实现类的代码,UserDetailsService是Java自带的类,UserDetailsServiceImpl继承UserDetailsService的loadUserByUsername方法
/** * 用户验证处理 * * @author ruoyi */ @Service public class UserDetailsServiceImpl implements UserDetailsService { private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class); @Autowired private ISysUserService userService; @Autowired private SysPasswordService passwordService; @Autowired private SysPermissionService permissionService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { SysUser user = userService.selectUserByUserName(username); if (StringUtils.isNull(user)) { log.info("登录用户:{} 不存在.", username); throw new ServiceException(MessageUtils.message("user.not.exists")); } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { log.info("登录用户:{} 已被删除.", username); throw new ServiceException(MessageUtils.message("user.password.delete")); } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { log.info("登录用户:{} 已被停用.", username); throw new ServiceException(MessageUtils.message("user.blocked")); } passwordService.validate(user); return createLoginUser(user); } public UserDetails createLoginUser(SysUser user) { return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user)); } }
到此这篇关于在Spring Security中,用户名和密码的验证流程的文章就介绍到这了,更多相关Spring Security用户名和密码验证内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于Spring Security中用户名和密码的验证完整流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!