跳转到主要内容

标签(标签)

资源精选(342) Go开发(108) Go语言(103) Go(99) angular(82) LLM(75) 大语言模型(63) 人工智能(53) 前端开发(50) LangChain(43) golang(43) 机器学习(39) Go工程师(38) Go程序员(38) Go开发者(36) React(33) Go基础(29) Python(24) Vue(22) Web开发(20) Web技术(19) 精选资源(19) 深度学习(19) Java(18) ChatGTP(17) Cookie(16) android(16) 前端框架(13) JavaScript(13) Next.js(12) 安卓(11) typescript(10) 资料精选(10) NLP(10) 第三方Cookie(9) Redwoodjs(9) LLMOps(9) Go语言中级开发(9) 自然语言处理(9) 聊天机器人(9) PostgreSQL(9) 区块链(9) mlops(9) 安全(9) 全栈开发(8) ChatGPT(8) OpenAI(8) Linux(8) AI(8) GraphQL(8) iOS(8) 软件架构(7) Go语言高级开发(7) AWS(7) C++(7) 数据科学(7) whisper(6) Prisma(6) 隐私保护(6) RAG(6) JSON(6) DevOps(6) 数据可视化(6) wasm(6) 计算机视觉(6) 算法(6) Rust(6) 微服务(6) 隐私沙盒(5) FedCM(5) 语音识别(5) Angular开发(5) 快速应用开发(5) 提示工程(5) Agent(5) LLaMA(5) 低代码开发(5) Go测试(5) gorm(5) REST API(5) 推荐系统(5) WebAssembly(5) GameDev(5) CMS(5) CSS(5) machine-learning(5) 机器人(5) 游戏开发(5) Blockchain(5) Web安全(5) Kotlin(5) 低代码平台(5) 机器学习资源(5) Go资源(5) Nodejs(5) PHP(5) Swift(5) 智能体(4) devin(4) Blitz(4) javascript框架(4) Redwood(4) GDPR(4) 生成式人工智能(4) Angular16(4) Alpaca(4) SAML(4) JWT(4) JSON处理(4) Go并发(4) kafka(4) 移动开发(4) 移动应用(4) security(4) 隐私(4) spring-boot(4) 物联网(4) nextjs(4) 网络安全(4) API(4) Ruby(4) 信息安全(4) flutter(4) 专家智能体(3) Chrome(3) CHIPS(3) 3PC(3) SSE(3) 人工智能软件工程师(3) LLM Agent(3) Remix(3) Ubuntu(3) GPT4All(3) 软件开发(3) 问答系统(3) 开发工具(3) 最佳实践(3) RxJS(3) SSR(3) Node.js(3) Dolly(3) 移动应用开发(3) 编程语言(3) 低代码(3) IAM(3) Web框架(3) CORS(3) 基准测试(3) Go语言数据库开发(3) Oauth2(3) 并发(3) 主题(3) Theme(3) earth(3) nginx(3) 软件工程(3) azure(3) keycloak(3) 生产力工具(3) gpt3(3) 工作流(3) C(3) jupyter(3) 认证(3) prometheus(3) GAN(3) Spring(3) 逆向工程(3) 应用安全(3) Docker(3) Django(3) R(3) .NET(3) 大数据(3) Hacking(3) 渗透测试(3) C++资源(3) Mac(3) 微信小程序(3) Python资源(3) JHipster(3) 大型语言模型(2) 语言模型(2) 可穿戴设备(2) JDK(2) SQL(2) Apache(2) Hashicorp Vault(2) Spring Cloud Vault(2) Go语言Web开发(2) Go测试工程师(2) WebSocket(2) 容器化(2) AES(2) 加密(2) 输入验证(2) ORM(2) Fiber(2) Postgres(2) Gorilla Mux(2) Go数据库开发(2) 模块(2) 泛型(2) 指针(2) HTTP(2) PostgreSQL开发(2) Vault(2) K8s(2) Spring boot(2) R语言(2) 深度学习资源(2) 半监督学习(2) semi-supervised-learning(2) architecture(2) 普罗米修斯(2) 嵌入模型(2) productivity(2) 编码(2) Qt(2) 前端(2) Rust语言(2) NeRF(2) 神经辐射场(2) 元宇宙(2) CPP(2) 数据分析(2) spark(2) 流处理(2) Ionic(2) 人体姿势估计(2) human-pose-estimation(2) 视频处理(2) deep-learning(2) kotlin语言(2) kotlin开发(2) burp(2) Chatbot(2) npm(2) quantum(2) OCR(2) 游戏(2) game(2) 内容管理系统(2) MySQL(2) python-books(2) pentest(2) opengl(2) IDE(2) 漏洞赏金(2) Web(2) 知识图谱(2) PyTorch(2) 数据库(2) reverse-engineering(2) 数据工程(2) swift开发(2) rest(2) robotics(2) ios-animation(2) 知识蒸馏(2) 安卓开发(2) nestjs(2) solidity(2) 爬虫(2) 面试(2) 容器(2) C++精选(2) 人工智能资源(2) Machine Learning(2) 备忘单(2) 编程书籍(2) angular资源(2) 速查表(2) cheatsheets(2) SecOps(2) mlops资源(2) R资源(2) DDD(2) 架构设计模式(2) 量化(2) Hacking资源(2) 强化学习(2) flask(2) 设计(2) 性能(2) Sysadmin(2) 系统管理员(2) Java资源(2) 机器学习精选(2) android资源(2) android-UI(2) Mac资源(2) iOS资源(2) Vue资源(2) flutter资源(2) JavaScript精选(2) JavaScript资源(2) Rust开发(2) deeplearning(2) RAD(2)

category

本文描述了依赖方(RP)可以使用联合凭据管理(FedCM)API通过身份提供程序(IdP)执行联合登录的过程。

调用get()方法


RP可以使用标识选项调用navigator.credential.get(),以请求用户使用他们已经在浏览器上登录的现有IdP帐户登录RP。IdP通过其客户端ID来识别RP,该客户端ID是由IdP在特定于IdP的单独进程中发布给RP的。IdP使用登录时提供给浏览器的凭据(cookie)来识别特定用户。

如果IdP成功验证了用户身份,该方法将返回一个承诺,该承诺将通过IdentityCredential对象实现。此对象包含一个令牌,该令牌包含已使用IdP的数字证书签名的用户身份信息。

RP将令牌发送到其服务器以验证证书,一旦成功,就可以使用令牌中的(现在受信任的)身份信息将他们登录到其服务(启动新会话),如果他们是新用户,则可以将他们注册到其服务,等等。

如果用户从未登录过IdP或已注销,则get()方法会拒绝并返回错误,RP可以将用户引导到IdP登录页面以登录或创建帐户。

注意:验证令牌令牌的确切结构和内容对FedCM API和浏览器是不透明的。IdP决定它的语法和用法,RP需要遵循IdP提供的说明(例如,请参阅验证服务器端的Google ID令牌),以确保他们正确使用它。

典型的请求可能如下所示:

JS

async function signIn() {
  const identityCredential = await navigator.credentials.get({
    identity: {
      context: "signup",
      providers: [
        {
          configURL: "https://accounts.idp.example/config.json",
          clientId: "********",
          nonce: "******",
          loginHint: "user1@example.com",
        },
      ],
    },
  });
}


identity.providers属性采用一个数组,该数组包含一个对象,该对象指定IdP配置文件(configURL)的路径和由IdP发布的RP的客户端标识符(clientId)。

注意:目前FedCM只允许使用单个IdP调用API,即identity.providers数组的长度必须为1。为了给用户提供身份提供者的选择,RP需要分别为每个提供者调用get()。这种情况将来可能会改变。

上面的示例还包括几个可选功能:

  • identity.context指定用户使用FedCM进行身份验证的上下文。例如,是首次注册此帐户,还是使用现有帐户登录?浏览器使用这些信息来改变其FedCM UI中的文本,以更好地适应上下文。
  • nonce属性提供一个随机的nonce值,以确保对此特定请求发出响应,从而防止重放攻击。
  • loginHint 属性提供有关浏览器应为用户登录提供的帐户选项的提示。此提示与IdP从帐户列表终结点提供的login_in提示值相匹配。

浏览器请求IdP配置文件,并执行下面详细介绍的登录流程。有关用户可能期望从浏览器提供的UI进行何种交互的更多信息,请参阅使用身份提供程序登录到依赖方。

FedCM登录流程


登录流程涉及三方——RP应用程序、浏览器本身和IdP。下图直观地总结了正在发生的情况。

下面详细描述的流程的可视化表示

fedcm
流程如下:

  1. RP调用navigator.credentials.get()来启动登录流。
  2. 浏览器从get()调用中提供的configURL请求两个文件:
    1. 众所周知的文件(/.aknowledge/web identity),可从configURL的eTLD+1上的/.aknowredge/web dentity获得。
    2. IdP配置文件(/config.json),可在configURL中获得。
    3. 这两个都是GET请求,它们没有cookie,也不遵循重定向。这有效地防止了IdP了解是谁提出了请求以及哪个RP试图连接。所有通过FedCM从浏览器发送的请求都包括一个Sec-Fetch-Dest:webidentity头,以防止CSRF攻击。所有IdP终结点都必须确认包含此标头。
  3. IdP使用请求的已知文件和config.json文件进行响应。浏览器根据已知文件中的有效配置URL列表验证get()请求中的配置文件URL。
  4. 如果浏览器将IdP的登录状态设置为“已登录”,则会向IdP配置文件内的accounts_endpoint发出认证请求(即使用标识登录用户的cookie),以获取用户的帐户详细信息。这是一个带有cookie的GET请求,但没有client_id参数或Origin标头。这有效地阻止了IdP了解用户试图登录的RP。因此,返回的帐户列表与RP无关。
    1. 注意:如果IdP登录状态为“logge-out”,则get()调用会拒绝NetworkError DOMException,并且不会向IdP的accounts_endpoint发出请求。在这种情况下,由开发人员来处理流,例如,通过提示用户转到并登录到合适的IdP。请注意,拒绝可能会有一些延迟,以避免将IdP登录状态泄露给RP。
  5. IdP使用从accounts_endpoint请求的帐户信息进行响应。这是与IdP相关联的任何RP的用户IdP cookie相关联的所有帐户的数组。
  6. 可选如果包含在IdP配置文件中,则浏览器会向client_metadata_endpoint发出一个无条件请求,以获取IdP服务条款和隐私策略页面的位置。这是一个发送的GET请求,其中clientId作为参数传递到GET()调用中,不包含cookie。
  7. 可选IdP使用从client_metadata_endpoint请求的URL进行响应。
  8. 浏览器使用前两个请求获得的信息来创建UI,要求用户选择登录RP的帐户(在有多个可用帐户的情况下)。UI还要求用户允许使用他们选择的联合IdP帐户登录RP。
    1. 注意:在这个阶段,如果用户以前在当前浏览器实例中使用联合RP帐户进行过身份验证(即使用RP创建了一个新帐户或使用现有帐户登录到RP的网站),则他们可能能够自动重新进行身份验证,这取决于在get()调用中中介选项的设置。如果是这样,一旦调用了get(),用户将自动登录,而无需输入凭据。有关更多详细信息,请参阅“自动重新身份验证”部分。
  9. 如果用户授予这样做的权限,浏览器会向id_assertion_endpoint发出一个有证书的请求,以从所选帐户的IdP请求验证令牌。凭据在HTTP POST请求中发送,其中包含cookie和内容类型为application/x-www-form-urlencoded。如果调用失败,将返回一个错误负载,如ID断言错误响应中所述,并且get()返回的promise将与错误一起被拒绝。
  10. IdP检查RP发送的帐户ID是否与已经登录的帐户的ID匹配,以及Origin是否与RP的Origin匹配,RP的Original将预先在IdP中注册。如果一切看起来都很好,它将使用请求的验证令牌进行响应。
    1. 注:当RP首次与IdP集成时,RP的起源将在一个完全独立的过程中与IdP注册。此过程将针对每个IdP。
  11. 流完成后,get()promise将使用IdentityCredential对象进行解析,该对象提供了进一步的RP功能。最值得注意的是,该对象包含一个令牌,RP可以验证该令牌来自IdP(使用证书),并且包含有关已登录用户的可信信息。一旦RP验证了令牌,他们就可以使用包含的信息让用户登录并启动新会话,为他们的服务注册等。令牌的格式和结构取决于IdP,与FedCM API无关(RP需要遵循IdP的指示)。

自动重新身份验证


FedCM自动重新身份验证允许用户在使用FedCM进行初始身份验证后尝试再次登录到RP时自动重新进行身份验证。“初始身份验证”是指用户在RP网站上的同一浏览器实例上首次通过FedCM登录对话框创建帐户或登录RP网站。

初始身份验证后,可以使用自动重新身份验证再次自动登录RP网站,而无需向用户显示“继续作为…”确认提示。如果用户最近授予了允许对特定帐户进行联合登录的权限,则立即强制执行另一个明确的用户确认没有隐私或安全方面的好处。

自动重新身份验证行为由get()调用中的中介选项控制:

JS

async function signIn() {
  const identityCredential = await navigator.credentials.get({
    identity: {
      providers: [
        {
          configURL: "https://accounts.idp.example/config.json",
          clientId: "********",
        },
      ],
    },
    mediation: "optional", // this is the default
  });

  // isAutoSelected is true if auto-reauthentication occurred.
  const isAutoSelected = identityCredential.isAutoSelected;
}


如果mediation 设置为可选或静默,则可以进行自动重新身份验证。

使用这些中介选项,自动重新身份验证将在以下条件下发生:

  1. FedCM可供使用。例如,用户没有在全局或RP的设置中禁用FedCM。
  2. 用户仅使用一个帐户通过FedCM在此浏览器上登录RP网站。
  3. 用户已使用该帐户登录到IdP。
  4. 在过去10分钟内没有进行自动重新身份验证。实施这一限制是为了阻止用户在注销后立即进行自动重新身份验证,这将导致用户体验非常混乱。
  5. RP在上一次登录后没有调用preventSilentAccess()。如果需要,RP可以使用它显式禁用自动重新身份验证。

当满足这些条件时,一旦调用get(),就会尝试自动重新验证用户。如果自动重新身份验证成功,用户将使用与以前相同的IdP帐户和验证令牌再次登录RP站点,而不会显示确认提示。

如果自动重新身份验证失败,则行为取决于所选的中介值:

  1. 可选:用户将看到对话框,并要求再次确认。因此,在用户旅程不在中间的页面(如RP登录页面)上使用此选项往往是有意义的。
  2. silent:get()promise将被拒绝,开发人员将需要处理引导用户返回登录页面以重新启动流程的问题。这个选项在用户旅程正在进行的页面上是有意义的,您需要让他们一直登录到完成,例如电子商务网站上的结账流程页面。

注意:IdentityCredential.isAutoSelected属性提供了是否使用自动重新身份验证执行联合登录的指示。这有助于评估API的性能,并相应地提高用户体验。此外,当它不可用时,可能会提示用户使用显式用户中介登录,这是一个带有中介的get()调用:必需。

另请参阅

文章链接