ruoyi项目登录验证变更(变更为使用公司windows的域登录进行验证)

17 篇文章 0 订阅

背景:我用的是ruoyi-vue3.8.6版本,因公司需要使用window的域+用户进行登录验证,因此原有的ruoyi登录验证方法就得替换掉

1. 首先登录系统添加一些域账号,以确保登录方式更改后,能在sys_user中找到该账号,因还需要使用ruoyi系统的权限部门等表,因此是不能直接删除掉原本的表结构
2. 更改登录验证:
 2.1更改逻辑:
##更改之前的逻辑
SysLoginController.java中的login方法会调用SysLoginService的login方法生成token,
login方法中authenticationManager.authenticate(authenticationToken);会调用UserDetailsServiceImpl的loadUserByUsername进行自定义校验

##思路
loadUserByUsername的validate方法会校验密码是否输入正确,但不仅仅于此,UserDetailsService的实现类有很多,因此就算直接修改了validate这个校验方法,依旧会被其他的实现类给校验失败,
最终决定剔除掉LoginUser loginUser = authentication.getPrincipal();的authentication相关调用方法,


##实现后需要删除的代码

并且执行下面的这些方法后,UserDetailsServiceImpl.java就可以删掉了,
configure(AuthenticationManagerBuilder auth)与bCryptPasswordEncoder方法也删除用不到加密了,

SysLoginService.java中的关于UserDetailsService的引用也需要删除,
同时SecurityConfig.java中的关于UserDetailsService的引用也需要删除,
2.2 真正实现(根据账号密码自己写校验,然后生成LoginUser,以下就是具体实现:):
1. 原SysLoginController.login方法保持不动,里面的login调用更改为以下:

		public String login(String username, String password){  //这个方法几乎是彻底重写
			LoginUser loginUser = loadUserByUsername(username, password);
			AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
			recordLoginInfo(loginUser.getUserId());

			return tokenService.createToken(loginUser);// 生成token
		}
		public LoginUser loadUserByUsername(String username, String password) throws UsernameNotFoundException {
			SysUser user = userService.selectUserByUserName(username);//数据库中获取这个账号信息
			if (StringUtils.isNull(user))
			{
				log.info("登录用户:{} 不存在.", username); //如果apo账号在系统中没有定义,那么就无法登录
				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(username, password); //把校验成功后的密码赋值给user中,再返回,避免Spring Security再次使用PasswordEncoder加密进行判断

			return createLoginUser(user);
		}

		public LoginUser createLoginUser(SysUser user) {
			return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
		}
	
	2. 上面调用的passwordService.validate(username, password); 方法也需要重写校验部分,如下:
		
			 public void validate(String username, String password){

				Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
				retryCount = retryCount == null?0 : retryCount;

				if (retryCount >= maxRetryCount){
					AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
							MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
					throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
				}

				if (!loginAPO(username, password)) {
					retryCount = retryCount + 1;
					AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
							MessageUtils.message("user.password.retry.limit.count", retryCount)));
					redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
					throw new UserPasswordNotMatchException();
				}else{
					clearLoginRecordCache(username);
				}
			}
			
	3.上面的loginAPO校验方法:这个就是我们公司域账号登录校验方法
        public boolean loginAPO(String username, String passwd){
				Hashtable<String, String> HashEnv = new Hashtable<>();
				HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
				HashEnv.put(Context.SECURITY_PRINCIPAL, "你们公司的域\\" + username);//必须有域,否则验证失败
				HashEnv.put(Context.SECURITY_CREDENTIALS, passwd);
				HashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
				HashEnv.put(Context.PROVIDER_URL,  "LDAP://xxx.xxx.xxx.xxx"); //域校验接口

				try {
					new InitialLdapContext(HashEnv, null);
					return true;
				} catch (Exception e) {
					return false; //这里也可以输出校验的错误信息
				}
			}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

往事不堪回首..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值