客户身份(CIAM)

根据id_token获取用户信息

在用户登录成功后,会返回用户身份令牌id_token给应用,应用通过用户身份令牌可以直接获取用户信息。应用首先获取身份令牌签名密钥,然后验证身份令牌的JWT签名,最后解析身份令牌中的用户信息。

# 获取身份令牌签名的秘钥

访问平台提供的jwk_uri地址:https://{your_domain}/api/v1/oauth2/keys,获取身份令牌签名秘钥。

pom文件引入:

<dependency>
	<groupId>com.nimbusds</groupId>
	<artifactId>nimbus-jose-jwt</artifactId>
	<version>5.7</version> <!-- 使用最新版本 -->
</dependency>
1
2
3
4
5

代码示例如下:

private List<RSAKey> getPublicKeys() throws Exception {
	List<RSAKey> rsaKeyList = new ArrayList();
	Request request = Request.Get("https://{your_domain)/api/v1/oauth2/keys");
	HttpResponse httpResponse = request.execute().returnResponse();
	if(httpResponse.getStatusLine().getStatusCode()==200){
		JSONObject jsonObject = JSONObject.parseObject(EntityUtils.toString(httpResponse.getEntity()));
		JSONArray keys = jsonObject.getJSONArray("keys");
		for (Object object:keys) {
			RSAKey rsaKey = RSAKey.parse(JSONObject.toJSONString(object));
			rsaKeyList.add(rsaKey);
		}
		return rsaKeyList;
	}else{
		logger.info("Failed to obtain identity token signature secret key!");
		throw new AuthenticationException(httpResponse.toString());
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 验证身份令牌签名

平台颁发的身份令牌是带有签名的JWT,签名算法为JWS标准RS256,当应用请求获取用户信息是,需先对身份令牌进行验证,包含以下方面:

验证签名:验证身份令牌的真实性和完整性。

pom文件引入:

<dependency>
	<groupId>com.nimbusds</groupId>
	<artifactId>nimbus-jose-jwt</artifactId>
	<version>5.7</version> <!-- 使用最新版本 -->
</dependency>
1
2
3
4
5

代码示例如下:

public boolean verifySignature(String id_token) {
	try {
		JWT jwtToken = JWTParser.parse(id_token);
		SignedJWT jwt = (SignedJWT)jwtToken;
		List<RSAKey> publicKeyList = getPublicKeys();
		RSAKey rsaKey = null;
		for (RSAKey key : publicKeyList) {
			if (jwt.getHeader().getKeyID().equals(key.getKeyID())) {
				rsaKey = key;
			}
		}
		if (rsaKey != null) {
			RSASSAVerifier verifier = new RSASSAVerifier(rsaKey.toRSAPublicKey());
			return jwt.verify(verifier);
		}else {
			logger.info("Can't verify signature for id token");
			return false;
		}
	} catch (Exception e) {
		logger.error("Failed to verify user token signature!",e.getMessage());
		return false;
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 解析身份令牌中用户信息

应用验证身份令牌签名有效后,通过base64解码出身份令牌中的HEADER与PAYLOAD部分,建议应用自行验证身份令牌其他信息(如当前时间是否超过过期时间、令牌接收者是否是本应用等),参数信息如下:

# HEADER部分

返回示例:

{
    "kid": "14a0b7d31d5d284c549f9e3565fb136a", 
    "alg": "RS256"
}
1
2
3
4

返回参数:

参数名 描述
kid 验证身份令牌签名时使用的秘钥id
alg 签名算法

# PAYLOAD部分

返回示例:

{
    "iss": "https://{your_domain}/api/v1/oauth2", 
    "aud": "XCNofcDPkSXFuBBgdgxNus5SO3Kiwka8", 
    "exp": 1655779413, 
    "jti": "B6P99VAWZQZBGNa4avp29s", 
    "iat": 1655779293, 
    "nbf": 1655779173, 
    "sub": "subject", 
    "name": "张三", 
    "mobile": "+86-18310131134", 
    "id": "20220616180055613-6F86-406AB6155", 
    "userName": "zhangsan", 
    "email": "18310131134@126.com"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

返回参数:

参数名 描述
iss 令牌签发人
aud 令牌接收者,应用的clientId
exp 令牌的过期时间
jti 令牌的id
iat 令牌的签发时间
sub 固定为subject
name 用户姓名
mobile 用户手机号
id 用户的id
userName 用户名
email 用户邮箱