客户身份(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
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
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
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
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
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
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 | 用户名 |
用户邮箱 |