oauth2 切换当前登录用户身份,角色及权限,无需重新登录

该代码段展示了在Spring Boot中处理用户身份切换和令牌更新的过程。通过PUT请求`/switchIdentity`,使用授权头和用户卡信息进行身份切换。同时,`updateToken`方法更新了用户的权限,包括角色和资源,并在认证信息变更后更新了OAuth2访问令牌。
摘要由CSDN通过智能技术生成

1. controller层

/**
	 * 切换用户身份
	 * */
	@PutMapping("/switchIdentity")
	public R switchIdentity(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader
			,@RequestBody UserCardsVO userCardsVO) {
		if (StrUtil.isBlank(authHeader)) {
			return R.ok(Boolean.FALSE, "退出失败,token 为空");
		}
		String token = authHeader.replace(OAuth2AccessToken.BEARER_TYPE, StrUtil.EMPTY).trim();

		return userService.switchIdentity(userCardsVO,token);

	}

2. 主要代码

public R<Boolean> updateToken(QhUser qhUser) {
			String[] permissions2 = ArrayUtil.toArray(qhUser.getPermissions(), String.class);

		OAuth2AccessToken accessToken = tokenStore.readAccessToken(qhUser.getToken());
		// 读取认证信息
		OAuth2Authentication authentication = tokenStore.readAuthentication(accessToken);

		Object principal = authentication.getPrincipal();
		if (principal instanceof PigxUser) {
			Set<String> dbAuthsSet = new HashSet<>();

			dbAuthsSet.add(SecurityConstants.ROLE + qhUser.getRoleId());
			// 获取资源
			dbAuthsSet.addAll(Arrays.asList(permissions2));

			Collection<? extends GrantedAuthority> authorities = AuthorityUtils
					.createAuthorityList(dbAuthsSet.toArray(new String[0]));

			// 构造security用户
			boolean enabled = StrUtil.equals(qhUser.getLockFlag(), CommonConstants.STATUS_NORMAL);
			PigxUser userDetails = new PigxUser(qhUser.getDeptIdList(), qhUser.getMail(), qhUser.getIntroduction(), qhUser.getStudyLevel(), qhUser.getStudentId(), qhUser.getIdentity(), qhUser.getNikeName(), qhUser.getId(),
					qhUser.getDeptId(), qhUser.getMainDeptId(), qhUser.getRoleId(), qhUser.getPhone(), qhUser.getAvatar(), qhUser.getTenantId(),
					qhUser.getUsername(), SecurityConstants.BCRYPT + qhUser.getPassword(), enabled, true, true,
					!CommonConstants.STATUS_LOCK.equals(qhUser.getLockFlag()), authorities);
			Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
			if (cache != null && cache.get(qhUser.getUsername()) != null) {
				cache.put(qhUser.getUsername(), userDetails);
			}

			if (authentication instanceof OAuth2Authentication) {
				OAuth2Authentication originalOAuth2Authentication = (OAuth2Authentication) authentication;
				if (!originalOAuth2Authentication.isClientOnly()) {
					Authentication userAuthentication = originalOAuth2Authentication.getUserAuthentication();
					if (userAuthentication instanceof UsernamePasswordAuthenticationToken) {
						//替换用户信息
						UsernamePasswordAuthenticationToken usernamePasswordAuthentication = new UsernamePasswordAuthenticationToken(userDetails, "N/A", authorities);
						usernamePasswordAuthentication.setDetails(userDetails);
						OAuth2Authentication oauth2Authentication = new OAuth2Authentication(originalOAuth2Authentication.getOAuth2Request(), usernamePasswordAuthentication);
						oauth2Authentication.setDetails(userDetails);

						//提取秘钥
						String key = authenticationKeyGenerator.extractKey(originalOAuth2Authentication);
						//这里获取auth_to_access不知道长可以去redis看 本项目用的是 base_oauth:auth_to_access:key:tenantId 每个项目用的可能不一样
						byte[] serializedKey =  serializationStrategy.serialize( keyStrResolver.extract(("pigx_oauth:" + "auth_to_access:"+qhUser.getTenantId() +":"+ key), StrUtil.COLON));
						byte[] bytes = null;
						RedisConnection conn = connectionFactory.getConnection();
						try {
							bytes = conn.get(serializedKey);
						} finally {
							conn.close();
						}
						//获取到token
						OAuth2AccessToken accessToken2 =serializationStrategy.deserialize(bytes,OAuth2AccessToken.class);

						// 更新缓存信息
						tokenStore.storeAccessToken(accessToken2, oauth2Authentication);
						return R.ok(Boolean.TRUE);
					}
				}
			}

		}
		return R.ok(Boolean.FALSE);
	}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值