AWS国内版Cognito身份池
# 说明
AWS Cognito组件用户池(Cognito User Pool)国内暂未上线,身份云IDaaS可完全替代Cognito用户池,借助身份云进行用户身份验证并融合Coginto身份池Identity Pool,实现对AWS资源的无缝安全访问。
本文介绍如何使用 IDaaS OpenID Connect 协议做为用户池(Cognito User Pool)的替代方案。我们将准备一个JavaScript示例demo示例,您可以根据自己的需求进行自定义。本示例主要演示竹云IDaaS作为身份提供者,允许用户使用IDaaS用户名和密码登录,来获取Cognito token。
# 术语说明
Cognito User Pool: Cognito用户池负责身份验证。最终用户可以通过用户池完成注册和登录过程。
Cognito Identity Pool: Cognito身份池负责授权(访问控制),授予最终用户使用AWS资源的权利。
竹云IDaaS:基于云原生身份云服务平台,可以取代Cognito用户池,在国内用户和AWS资源之间架起一座桥梁,以下简称IDaaS或平台。
# 身份验证流程
流程说明
用户访问示例demo示例并单击“使用IDaaS登录”按钮。
该demo示例将用户重定向到IDaaS进行登录。成功验证后,该demo示例会从IDaaS接收ID Token。
该demo示例将ID Token交换成Cognito令牌。
该demo示例将Cognito令牌交换成临时AWS安全凭据。
该demo示例使用凭据访问AWS服务。
# 前提条件
- AWS帐户。如果您没有,您可以免费开始使用AWS (opens new window)。
- 用于托管示例demo示例的web服务器。
# IDaaS配置
登录IDaaS企业中心【资源】->【应用】->【添加自建应用】,应用名称可以写【Cognito OIDC示例】,认证集成选择【OIDC】。
配置应用认证参数。
- 回调地址:请指定Web服务器上Callback.html文件的路径。示例:https://localhost/callback.html
- 隐式授权模式:本demo示例需要将隐式授权模式开启,如果您的应用程序是后端和IDaaS集成,您也可以选择关闭隐式授权模式,使用授权码模式,通过授权码来获取 ID Token,以便 Demo 中使用 IDaaS 的 ID Token 交换 Cognito 令牌。
请记住IDaaS应用的 ClientId , 我们将提供给 AWS 作为 OpenId Connect 身份提供商的“受众”。
- 应用左侧菜单栏下切换至 【授权管理】->【应用账号】” 页签,添加账号。
# AWS IAM 配置
登录 AWS Console。
在“All services”选择“身份和访问管理(IAM)”。
选择“身份提供商”。
点击“添加提供商”,选择“OpenID Connect”。
填写“提供商 URL”:示例:https://{yourdomain}/api/v1/oauth2, 更换示例中yourdoamin为您的IDaaS域名,点击【获取指纹】。
填写“受众”:您的IDaaS应用的 ClientId,即您在上一步IDaaS平台建的应用,保存成功。
请记您的提供商名称,因为我们稍后在创建示例demo示例时需要它,示例:{yourdomain}/api/v1/oauth2
# AWS Cognito 配置
登录 AWS Console。
在“All services”选择“Cognito”。
选择您的身份池, 如果没有身份池,请“创建身份池”。
配置身份池信任,选择身份来源:OpenID Connect (OIDC),点击“下一步”。
创建IAM角色名称,示例:Cognito_IDaaSAuth_Role。可以查看策略详情,Cognito自动增加GetCredentialsForIdentity权限
{
"Effect": "Allow",
"Action": [
"cognito-identity:GetCredentialsForIdentity"
],
"Resource": [
"*"
]
}
2
3
4
5
6
7
8
9
- 选择您前面建的身份提供商,点击保存。
请记住身份池ID,因为我们稍后在创建示例demo示例时需要它。
# 创建示例程序
- demo示例只包含两个文件 — index.html和callback.html。在本节中,我将显示这两个文件的完整代码列表。接下来,您只需要分别更新文件中三个变量,然后将它们部署到您的服务器中。
# index.html
index.html文件显示“使用IDaaS登录”按钮,并将用户重定向到IDaaS进行身份验证。此文件是示例demo示例的起点。它需要配置您的应用的 ClientId,这就是IDaaS知道登录请求来自哪个demo示例的方式。
下面列出index.html的完整标记和代码,您还需要以下三步:
替换JavaScript代码中的client_id为您的 ClientId,即您在【IDaaS配置】获取的IDaaS应用的 ClientId
替换JavaScript代码中的redirect_uri为您的demo示例的callback.html地址。
替换JavaScript代码中的url中yourdomain为您的域名,即IDaaS域名。
<!DOCTYPE html>
<html>
<head>
<title>IDaaS Cognito OIDC 示例</title>
</head>
<body>
<h2>IDaaS and Amazon Cognito OpenID 集成示例</h2>
<p>
本demo演示IDaaS如何与Amazon Cognito通过OIDC集成的web应用程序示例,该示例允许用户使用其IDaaS用户名和密码登录并获得Cognito令牌。
</p>
<p>本demo完全使用JavaScript编写,仅包含两个文件 - <b>index.html</b> 和 <b>callback.html</b>.</p>
<p>首先,请点击 <b><button onclick="login()">使用IDaaS登录Demo</button></b>。如果认证成功,我们将会跳转 <b>callback.html</b>,并成功展示Cognito令牌。</p>
</body>
<script type="text/javascript">
function login() {
// 替换IDaaS应用的 ClientId
var client_id = 'yeMSd6WRMnNoVXXXXXXncXLV9l2jXZ';
// 替换callback.html地址
var redirect_uri = 'https://localhost/callback.html';
// 替换url中yourdomain为您的域名,即IDaaS域名
var url = 'https://{yourdomain}/api/v1/oauth2/authorize'
+ '?response_type=token id_token'
+ '&scope=openid'
+ '&nonce=abc'
+ '&client_id=' + client_id
+ '&redirect_uri=' + redirect_uri;
window.location.replace(url);
}
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# callback.html
callback.html是用户登录后IDaaS将其重定向到demo示例时看到的页面。
下面列出callback.html的完整标记和代码,您还需要以下三步:
替换JavaScript代码中的aws_region为您的Cognito用户池地区。
替换JavaScript代码中的provider_url中yourdomain为您的域名,即您在【AWS IAM 配置】获取的提供商名称。
替换JavaScript代码中的pool_id为您的身份池ID,即您在【AWS Cognito 配置】获取的身份池ID
<!DOCTYPE html>
<html>
<head>
<title>IDaaS Cognito OIDC 示例</title>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.850.0.min.js"></script>
</head>
<body onload="callback()">
<h2>IDaaS 和 Amazon Cognito OpenID 集成示例</h2>
<h4><span id="Error" style="color:#FF0000"></span></h4>
<h4><span id="IdentityId" style="color:#2196f3"></span></h4>
<h4><span id="AccessKeyId" style="color:#2196f3"></span></h4>
<h4><span id="SecretKey" style="color:#2196f3"></span></h4>
<h4><span id="SessionToken" style="color:#2196f3;word-break:break-all"></span></h4>
<h4><span id="Expiration" style="color:#2196f3"></span></h4>
</body>
<script type="text/javascript">
function callback() {
var url = window.location.href;
var error = url.match('error=([^&]*)')
if (error) {
var description = url.match('error_description=([^&]*)')
printMessage('Error', 'Error: ' + error[1] + '<br>Description: ' + description[1] + '</br>');
return;
}
var match = url.match('id_token=([^&]*)');
if (match) {
var id_token = match[1];
if (id_token) {
printMessage('Error', '<span style="color:#000000">使用IDaaS的ID Token获取Cognito令牌</span>');
makeCognitoRequest(id_token);
}else{
printMessage('Error', 'Error: 无法从URL中检索id token');
}
}else{
printMessage('Error', 'Error: URL中没有id token');
}
}
async function makeCognitoRequest(id_token) {
// 替换aws_region为您的Cognito用户池地区
var aws_region = 'cn-north-1';
// 替换provider_url中yourdomain为您的域名
var provider_url = '{yourdomain}/api/v1/oauth2';
// 替换pool_id为您的身份池ID
var pool_id = 'cn-north-1:469392b9-XXXX-XXXX-9877-7d34c3ca2a47';
var logins = {};
logins[provider_url] = id_token;
AWS.config.region = aws_region;
try {
const cognitoIdentity = new AWS.CognitoIdentity();
const { IdentityId } = await cognitoIdentity.getId({
IdentityPoolId: pool_id,
Logins: logins
}).promise()
const { Credentials } = await cognitoIdentity.getCredentialsForIdentity({
IdentityId: IdentityId,
Logins: logins
}).promise()
printMessage('IdentityId', '<span style="color:#000000">IdentityId: </span>' + IdentityId);
printMessage('AccessKeyId','<span style="color:#000000">AccessKeyId: </span>' + Credentials.AccessKeyId);
printMessage('SecretKey','<span style="color:#000000">SecretKey: </span>' + Credentials.SecretKey);
printMessage('SessionToken','<span style="color:#000000">SessionToken: </span>' + Credentials.SessionToken);
printMessage('Expiration','<span style="color:#000000">Expiration: </span>' + Credentials.Expiration);
} catch (e) {
printMessage('Error', e);
}
}
function printMessage(elementId, messageString){
document.getElementById(elementId).innerHTML = messageString;
}
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 登录验证
现在一切就绪,可以测试示例demo示例。
在index.html页面中,单击使用IDaaS登录Demo。
使用您的IDaaS用户名和密码登录。
登录成功后将重定向到callback.html页面。您将看到以下AWS临时凭证。
使用AWS临时凭证,访问AWS服务,如API 网关,S3, IoT, AI 等服务。