SSO单点登录设计【Demo实例】

以下为部分代码实现

	/**
	 * 生成授权token
	 * @param person
	 */
	public String generateSSOToken(User user) {
		//生成 sso token,保存到redis中
		String token = UUID.randomUUID().toString();
		redisTemplate.opsForValue().set(user.getUid(), token, 5, TimeUnit.MINUTES);
		redisTemplate.opsForValue().set(token, user.getUid(), 5, TimeUnit.MINUTES);
		return token;
	}

	/**
	 * 删除授权token
	 * @param person
	 */
	private void deleteSSOToken(User user) {
		//清空 sso token
		String token = (String) redisTemplate.opsForValue().get(user.getUid());
		redisTemplate.opsForValue().getOperations().delete(token);
		redisTemplate.opsForValue().getOperations().delete(user.getUid());
	}

	/**
	 * 根据sso token返回对应的数据信息
	 * @param token
	 * @return
	 */
	public Map<String, Object> getInfoFromSSOToken(String token) {
		if(StringUtil.isBlank(token)) {
			return null;
		}
		
		Map<String, Object> result = new HashMap<String, Object>();
		
		if(redisTemplate.opsForValue().getOperations().hasKey(token)) {
			String uid = (String)redisTemplate.opsForValue().get(token);
			result.put("uid", uid);
			
			//使用过的token需要清理掉,避免重复滥用
			User user = new User();
			user.setUid(uid);
			this.deleteSSOToken(user);
				
			return result;
		}else {
			return null;
		}
		
		return null;
	}

generateSSOToken()方法主要是生成token,同时将token对应的授权信息保存到Redis中(代码中只保存了uid,大家可以根据需要再添加需要保存的授权信息)。 另外,为了后面通过用户的ID获取对应token的方便,我还将uid:token这个键值对保存到了Redis中。 关于在generateSSOToken()之前的用户名/密码登录的代码,这里没有贴出来,因为各个系统都有自己的用户名/密码的存储和验证方式(我目前使用的是LDAP Server存储用户信息)。

deleteSSOToken()方法,主要用来清除token,在用户退出登录以及使用过的token都需要及时清理掉,避免token滥用。同时,为了避免非正常的用户退出的情况,我在generateSSOToken()方法中也设置了token在Redis中的失效时间。

getInfoFromSSOToken()方法,主要是用户第三方系统通过token来获取授权信息,当token不使用后,需要调用deleteSSOToken()方法来删除已经使用过的token。

2018年1月8日

Last Updated:
Contributors: 小5