基于AWS Cognito实现跨账号Web应用SSO集成技术问询
实现合作伙伴Cognito用户无缝访问我方SPA的解决方案
针对你提出的需求(合作伙伴用户已登录自身Cognito系统,点击链接无需二次登录即可访问我方预置了对应用户的SPA),以下是具体解决方案及对四个疑问的答复:
1. 合作伙伴是否需要变更其Cognito配置?
需要,主要是适配OIDC集成的配置:
- 在其Cognito用户池的应用客户端中,添加我方SPA的域名到
允许的回调URL和允许的源URL; - 确保其用户池启用了OIDC功能(默认已启用),能生成标准的ID Token/Access Token;
- 建议创建一个独立的应用客户端用于和我方集成,避免影响现有业务。
2. 我方Cognito用户池需做哪些配置?
方案一:OIDC联邦静默SSO(推荐,标准流程)
- 添加合作伙伴Cognito为OIDC身份提供商:
- 进入我方Cognito用户池的「身份提供商」页面,选择「OIDC」类型,填入合作伙伴Cognito的OIDC元数据地址(格式:
https://cognito-idp.<区域>.amazonaws.com/<用户池ID>/.well-known/openid-configuration); - 配置授权范围至少包含
openid和用于用户匹配的属性(如email),并设置用户属性映射(比如将对方ID Token的email映射到我方用户池的email字段,确保双方预置用户的该属性一致);
- 进入我方Cognito用户池的「身份提供商」页面,选择「OIDC」类型,填入合作伙伴Cognito的OIDC元数据地址(格式:
- 修改我方SPA的应用客户端:
- 添加合作伙伴网站域名到
允许的源URL; - 启用授权码流(比隐式流更安全),并确保
允许的回调URL包含我方SPA的地址; - 可选:启用「静默登录」支持,减少重定向感知。
- 添加合作伙伴网站域名到
方案二:自定义认证(无跳转,需密钥协作)
- 在我方Cognito用户池的「触发器」中,启用「自定义认证」触发器;
- 创建KMS对称密钥,和合作伙伴共享公钥(或约定签名算法/密钥),用于验证对方发送的用户断言。
3. 合作伙伴网站的访问链接方式
对应方案一(OIDC静默SSO)
使用带授权参数的GET链接,用户点击后会触发静默授权流程(因已登录合作伙伴Cognito,无感知重定向后返回我方SPA):
https://我方SPA域名?response_type=code&client_id=我方应用客户端ID&redirect_uri=我方SPA回调地址&scope=openid email&state=随机字符串&nonce=随机字符串&identity_provider=合作伙伴OIDC提供商名称
其中identity_provider参数指定直接使用合作伙伴的Cognito作为身份源,跳过我方默认登录页。
对应方案二(自定义认证)
合作伙伴生成包含用户唯一标识(如email)的签名JWT断言,将其作为参数附加到链接中:
https://我方SPA域名?assertion=签名后的JWT字符串
4. 我方React SPA代码修改
方案一(OIDC静默SSO)
基于Amplify Auth实现自动触发静默登录:
import { Amplify, Auth } from 'aws-amplify'; import awsconfig from './aws-exports'; // 初始化Amplify时追加OIDC提供商配置 Amplify.configure({ ...awsconfig, Auth: { oauth: { domain: '我方Cognito域名', scope: ['openid', 'email'], redirectSignIn: '我方SPA回调地址', redirectSignOut: '我方SPA注销地址', responseType: 'code', identityProviders: { '合作伙伴OIDC提供商名称': { domain: '合作伙伴Cognito域名', clientId: '合作伙伴应用客户端ID', } } } } }); // 页面加载时检测授权参数并触发登录 useEffect(() => { const urlParams = new URLSearchParams(window.location.search); const idp = urlParams.get('identity_provider'); if (idp) { Auth.federatedSignIn({ provider: idp }) .then(() => window.location.href = '/') // 登录成功跳首页 .catch(err => console.error('静默登录失败:', err)); } else { // 常规登录状态检查 Auth.currentAuthenticatedUser().catch(() => window.location.href = '/login'); } }, []);
方案二(自定义认证)
解析链接中的断言并调用Cognito自定义认证:
import { Auth } from 'aws-amplify'; import jwtDecode from 'jwt-decode'; useEffect(() => { const urlParams = new URLSearchParams(window.location.search); const assertion = urlParams.get('assertion'); if (assertion) { // 从断言中解析用户标识(如email) const decoded = jwtDecode(assertion); const username = decoded.email; // 触发自定义认证流程 Auth.signIn({ username, password: assertion, // 将断言作为"密码"传入,由Cognito触发器验证 authenticationFlowType: 'CUSTOM_AUTH' }) .then(() => window.location.href = '/') .catch(err => console.error('自定义认证失败:', err)); } }, []);
注:需安装jwt-decode库解析JWT,同时我方Cognito的自定义认证触发器要实现断言签名验证逻辑。
内容的提问来源于stack exchange,提问作者souser
相关产品推荐
相关产品推荐

