现代识别标准:OAuth 2.0,OpenID Connect,WebAuthn

放还是不放?就是那个问题…

现在,在许多站点上,我们看到了使用社交网络进行注册或登录的机会,并且某些站点提供了使用外部安全密钥或指纹的功能。它是什么?设计合理的安全标准或专有实施?我们可以信任这些技术并将其用于网站开发和日常生活吗?让我们做对。因此,现在有几种用于标识OAuth 2.0,OpenID Connect,WebAuthn,SAML 2.0,凭据管理API等用户的标准和技术。在本文中,我将讨论三种最有前途的协议OAuth 2.0,OpenID Connect和WebAuthn。为了了解如何将它们付诸实践,我们将做三个实验室工作。我们将使用GitHub和Google作为识别用户的平台。在大多数帐户上。

图片

OAuth 2.0


让我们从最著名的OAuth 2.0协议开始。它于2012年作为RFC 6749发布:OAuth 2.0授权框架

使用OAuth 2.0,用户允许特定站点从社交网络接收其私人数据,但无需将其登录名/密码传输到该站点。例如,当您通过Facebook在站点上注册时,您只授予该站点权限即可从Facebook获取您的姓名,电子邮件地址和其他私人数据。

让我们处理技术实施。为简单起见,我将称呼在社交网络上存储用户凭据的任何站点。MySite将命名任何要从社交网络获取用户数据的站点或应用程序。

图片

该标准定义了以下角色:

  • Resource Owner — , MySite .
  • Client ( MySite) — , Authorization Server Resource Server .
  • Authorization Server — / , .
  • Resource Server — , API. Authorization Server Resource Server .

Authorization flow


  • MySite :
  • MySite Name ( ), Homepage ( MySite) Callback (, )
  • 社交网络给出客户端ID(有时称为AppID)和客户端密钥。
  • 开发者ID必须在客户ID和客户密码中注册。

现在过程本身。具体实现的细节可能有所不同,但一般逻辑将始终如下:

图片

  1. 资源所有者登录到客户端(MySite),选择“使用社交网络登录”选项,站点将用户重定向到授权服务器上的社交网络。
  2. 授权服务器检查用户是否具有活动会话,如果没有,则显示登录表单。
  3. 资源所有者输入他的用户名/密码,并确认MySite可以使用某些私人数据,例如用户名或电子邮件地址。
  4. 授权服务器验证用户并使用验证结果和“授权码”重定向到回调地址
  5. Client “Authorization Code”, Client ID Client Secret.
  6. Authorization Server “access token” JWT (JSON Web Token), . JWT “refresh token”, c .
  7. Client API, “access token”.
  8. Resource Server “access token” (, Authorization Server) .

OAuth 2.0 (GitHub)


关于如何使用社交网络实施OAuth 2.0授权的说明很多。我个人喜欢以下文章:使用GitHub OAuth 2.0和NodeJS进行身份验证它详细说明了步骤并提供了测试程序。但是要真正理解该算法,最好动手完成所有步骤(来自浏览器的http请求或curl的调用)。走。

首先,在GitHub上注册您的应用程序:github.com/settings/applications/new

设置参数:


为了授权在其自己的站点内工作,这些地址必须真实,但这对于实验室工作不是必需的。

从GitHub获取:

  • 客户端ID:ab8ec08a620c2
  • 客户端密钥:e6fdd52b0a99e8fbe76b05c1b7bb93c1e

当然,在所有实验室工作中,所有价值都是假的。

这是在GitHub网站上获取客户端ID和密钥的样子:

图片

现在开始授权。我们认为第1步已经完成:用户登录MySite并选择“使用GitHub登录”。呼叫流程的第2步是REST格式的呼叫:

https://github.com/login/oauth/authorize?client_id=ab8ec08a620c2


  • 该地址是github上的登录点
  • client_id是注册期间发布的客户ID

此次调用的结果是,GitHub显示了一个授权窗口:

图片

步骤3:输入登录名/密码以访问GitHub

步骤4:GitHub将请求重定向到首页,在此请求中,我们看到代码:

http://MySite/home?code=a29b348f63d21

此地址上没有工作站点,但是对我们来说,最主要的是知道发送的代码构成下一个步骤5:

https://github.com/login/oauth/access_token?client_id=ab8ec08a620c2&
client_secret=e6fdd52b0a99e8fbe76b05c1b7bb93c1e&
code=a29b348f63d21

  • 该地址是GitHub上的访问令牌接收点
  • client_id是注册期间发布的客户ID
  • client_secret是注册期间发布的客户端密钥
  • 代码是刚刚发送的代码

步骤6:作为回应,收到访问令牌:

access_token=31b71cbd372acdbb20ec1644b824f3dd0&scope=&token_type=bearer

步骤7:将access_token插入请求标头,然后调用GitHub API:

curl -H "Authorization: token 31b71cbd372acdbb20ec1644b824f3dd0" https://api.github.com/user

步骤8:作为回应,我们获得了JSON,其中包含有关我的有用信息,您可以使用这些信息在MySite上创建配置文件:

{
  "login": "AlexeySushkov",
  "html_url": "https://github.com/AlexeySushkov",
  "repos_url": "https://api.github.com/users/AlexeySushkov/repos",
  "name": "Alexey Sushkov",
  "blog": "http://sushkov.ru",
  "location": "St.Petersburg, Russia",
  "email": "alexey.p.sushkov@gmail.com",
 ..
}  

实际上,我们仅研究了一种OAuth 2.0方案。有几种方案,每种方案的使用取决于应用程序,安全性考虑因素,部署方法等。可以找到所有方案的描述,例如,在这里:Nutshell中的OAuth 2.0

Openid连接


对OAuth 2.0有点了解。现在,让我们找出为什么需要OpenID Connect,它是OAuth 2.0的附加组件:

  • C OAuth 2.0 .. access token, . access token MySite. OpenID Connect — (identity). .
  • OpenID Connect “service discovery”. SSO (Single Sign-On), .

让我们从技术角度看一下标准。

OpenID Connect(OIDC)是由OpenID Foundation联盟开发的开放OpenID标准OIDC扩展了OAuth 2.0的主要功能:

  • 除访问令牌和刷新令牌外,授权服务器还返回“身份令牌”(ID令牌)。它包含在同一JWT中。可以从ID令牌中提取以下信息:用户名,登录时间,ID令牌到期日期。令牌ID可以在参与者之间转移。
  • OIDC提供了附加的API,使您可以请求有关用户及其当前会话的信息。

OpenID Connect中的交互图看起来与OAuth相同。请求内容的唯一区别是:

  • 在最初的代码请求中,添加了一个附加属性scope = openid。
  • 该算法的结果是,客户端除了访问和刷新令牌外,还会收到令牌ID。

OpenID Connect:实验室(Google)


现在,让我们看看Google在这个主题上能取悦我们什么。有关配置和使用Google的OpenID Connect的详细说明,以及使用Google API的沙箱的详细说明Google OAuth 2.0 Playground

在这里,与OAuth 2.0的情况一样,我们将逐步进行操作并查看传入的数据。同样,我们认为该应用程序已注册,已收到客户端ID和客户端密钥,并通过了步骤1。呼叫流程的第2步是REST格式的呼叫:

https://accounts.google.com/o/oauth2/v2/auth?
response_type=code&
client_id=140797064495-b8b79j42m97nkkrlndfstikv8.apps.googleusercontent.com&
scope=openid%20email&
redirect_uri=http%3A//c18529.shared.hc.ru/wp-login.php&
state=765439764

Google有点复杂,因为 他们更加注意安全性:

  • 地址是Google的登录点
  • response_type =代码-希望收到响应代码
  • client_id-注册期间发布的客户ID
  • scope = openid电子邮件-我们要访问哪些数据
  • redirect_uri-在应用程序注册期间指定的redirect_uri
  • state-客户端生成的编号,在客户端和AS之间传输以防止入侵者干扰。

步骤3:没有密码输入表单,因为 我已经登录到Google。

步骤4:Google将请求重定向到首页,在此请求中,我们看到以下代码:

http://MySite?state=123&code=4/xAFkcMzhyJhUErRJYwIyntSYN-WeJjfZHLiwWL4IaT-WkHzMU18xABlPmev-M_87wVbqTkQ1y93w6GB5&scope=email+openid+https://www.googleapis.com/auth/userinfo.email&authuser=0&prompt=none

与GitHub一样,此地址上没有可用的网站,但这不是必需的,对我们来说,主要的事情是知道代码以形成下一步5。这也更加复杂,因为 Google需要POST请求,而不是GET请求:

curl -d "code=4/xAFkcMzhyJhUErRJYwIyntSYN-WeJjfZHLiwWL4IaT-WkHzMU18xABlPmev-M_87wVbqTkQ1y93w6GB5&client_id=140797064495-b8b79j42m97nkkrlndfstikv8.apps.googleusercontent.com&
client_secret=HMVctrTicW6RC1Q8T&
redirect_uri=http%3A//c18529.shared.hc.ru/wp-login.php&
grant_type=authorization_code" 
-H "Content-Type: application/x-www-form-urlencoded" -X POST https://oauth2.googleapis.com/token

  • 地址是Google上的令牌接收点
  • 代码是刚刚发送的代码
  • client_id是注册期间发布的客户ID
  • client_secret是注册期间发布的客户端密钥
  • grant_type = authorization_code-标准中唯一的有效值

步骤6:作为回应,收到access_token和id_token:

{
  "access_token": "ya29.Il_AB0KeKnjBJx0dhjm2nCLt1B-Mq0aQBW5T302JnlZfsxW1AXqLFfDJZRMi2R2WKG4OX4msKLjx4E4CSl4G_4ajAy3aqrf4pM0ic0jJr092pA67H9aktJktCbx",
  "expires_in": 3327,
  "scope": "openid https://www.googleapis.com/auth/userinfo.email",
  "token_type": "Bearer",
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3ZDU1ZmY0ZTEwOTkxZDZiMGVmZDM5MmI5MWEzM2U1
………………………………_…………………………………………………….._4mUTiMNSAHljap1hLD2hAzgOZWuQ"
}

现在如何处理这笔财富?

第7步:使用access_token,一切都变得清晰:我们将其包含在API调用中,例如GMail:

curl -H "Authorization: Bearer ya29.a0Adw1xeWvFoxHKNICHnV6vFFj5TZdPQVlYD98h8wjW95ZEbHVui_pk7HGRoq3Q7MlVLV23xkVM0yyjSP8ClSlvfUy3b_IqvKQW5Lvwj38QzJhee-aH1grerB4pRpMzn_FGueigG_RGI56pKPgFBTr49cpynQy" https://www.googleapis.com/gmail/v1/users/alexey.p.sushkov@gmail.com/profile

步骤8:作为回应,我们获得了带有有用信息的JSON:

{
 "emailAddress": "alexey.p.sushkov@gmail.com",
 "messagesTotal": 372543,
...
}

现在,让我们检查一下id_token包含用于验证用户身份和维护会话的信息的语句。为此,您需要解密内容。最简单的方法是通过
oauth2.googleapis.com/tokeninfoGoogle API联系,并将接收到的id_token指定为参数:

https://oauth2.googleapis.com/tokeninfo?id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3ZDU1ZmY0ZTEwOTkxZDZiMGVmZDM5MmI5MWEzM2U1NGMwZTIxOGIiLCJ0eXAiOi
………………………_……………………………...
SVQ5GQni3irfOzOXYEiqijp6TjGa_a-3jKcEsU5TbasZmAIejsdVcNy2_4mUTiMNSAHljap1hLD2hAzgOZWuQ

得到了JSON:
{
  "iss": "https://accounts.google.com",
  "email": "alexey.p.sushkov@gmail.com",
  "email_verified": "true",
  "iat": "1583257010",
  "exp": "1583260610",
  "typ": "JWT"
...
}

我们看到id_token包含有关用户登录,接收时间和令牌寿命的信息。我们可以得出结论,来自Google的OpenID Connect正在运行,并且可以用于相关方案。

网络认证


Web身份验证API(也称为WebAuthn):

  • 该标准允许用户使用外部安全密钥(例如USB密钥)或指纹,然后通过其他生物特征数据(面部,视网膜)在网站和应用程序中标识自己。
  • — / «Public key cryptography». Public key cryptography — , . Private key ( ) , public key ( ) .
  • W3C (World Wide Web Consortium) FIDO, Google, Mozilla, Microsoft, Yubico. W3C HTTP, HTML, XML . WebAuthn. WebAuthn : Chrome, Firefox, Edge, Safari.


与OAuth 2.0相比,WebAuthn添加了以下角色:

Authenticator:一个外部安全密钥(物理介质或指纹扫描仪),该密钥使用各种技术(例如,Bluetooth / NFC / USB)对用户进行身份验证。服务于:

  • 生成公钥证书(公钥/私钥对)。
  • 身份验证器将私钥安全地存储在其内存中
  • 将公钥传递给外部系统
  • 用私钥签名数据并将结果传输到外部系统

Authenticator使用CTAP协议(客户端到Authenticator协议)与浏览器进行交互。

信赖方:执行与OAuth 2.0中的“授权服务器”相同的功能,即验证用户的身份。仅在OAuth 2.0中,它是用户名/密码,在WenAuthn中,它是公钥凭据。

用户代理:集成了浏览器和网络应用程序,其功能与OAuth 2.0中的客户端相同,即,一方面与用户交互并为其提供GUI,另一方面与存储用户凭据的系统进行交互。

授权流程


在开始身份验证过程之前,就像在OAuth 2.0中一样,您需要执行准备步骤,仅在OAuth 2.0中我们注册了应用程序,在WebAuth 2.0中我们注册了用户。Web身份验证API指定两个调用:

  • navigator.credentials.create-创建用户凭证
  • navigator.credentials.get-验证用户凭据

因此,要注册,您必须调用navigator.credentials.create。

因此,用户的身份验证器将存储特定站点的私钥,而公钥将存储在依赖方中。

图片

之后,身份验证过程将如下所示:

图片

  1. “WebAuthn”. , , WebAuthn, “ ” “ ”. Relying Party Challenge. Challenge — , Code OAuth 2.0.
  2. Relying Party Challenge. , REST API.
  3. Authenticator- CTAP (Client to Authenticator Protocols). navigator.credentials.get c :

    • Challenge
  4. Authenticator , , .
  5. , Authenticator .
  6. 该应用程序将签名的数据发送给依赖方。
  7. 信赖方使用公钥解密数据,检查质询并授权用户。

要修复材料,我们需要进行实验室工作:

WebAuthn:实验(Google)


要实施WebAuthn,只能放弃http请求,因为您需要调用浏览器API与Authenticator交互。但是,在这里Google很高兴,通过一步一步的说明制作了一个沙箱:您的第一个WebAuthn

作为工作的结果,我们获得了一个实现指纹身份验证的JS客户端-服务器应用程序。一个可运行的deme位于

如果在带有指纹传感器的智能手机上运行它,则可以看到工作结果。像往常一样,首先准备-注册用户:

图片

创建用户名/密码,然后附加指纹:

图片

之后,程序显示该指纹附加了哪个公钥:

图片

现在,您可以启动身份验证脚本。和往常一样,我们认为第1步已经完成,并且我们已经在现场。要转到步骤2,请单击“尝试重新认证”。浏览器将执行第3步并与Authenticator交互,在第4步中将要求您放手指:

图片

并且如果已连接手指,则第5步和第6步将成功通过,在第7步中,应用程序将再次显示带有相应公钥的窗口:

图片

结论


因此,我们研究了三种最常见且最有前途的用户识别协议:OAuth 2.0,OpenID Connect,WebAuthn。我们了解了其适用范围:

  • OAuth 2.0-用于通过社交网络将用户注册并登录到站点。并从社交网络获取用户数据。
  • OpenID Connect — . OpenID Connect SSO .
  • WebAuthn — .


  • , , .
  • , , .
  • 验证用户到Facebook或Google之类的云平台的身份很有意义,因为 他们聘请了能够提供所有安全细微差别的最佳安全专家。
  • 我建议对未来保持乐观,因为 WebAuthn协议-摆脱密码时代的真正机会!

这仅仅是开始!

附录:其他身份验证协议


为了完整起见,我将列出用于识别用户的其他相关协议和技术:

SAML 2.0(安全性声明标记语言)


2005年的协议已经成熟,但是用于构建SSO系统的方案集有限。使用基于XML的数据格式。可以在文章中找到更多详细信息:“谁使用SAML 2.0身份验证协议”

凭证管理API


开发由与WebAuthn-W3C相同的组织进行。凭据管理标准允许您:

  • 存储订户的身份,这使用户无需输入密码即可访问站点,但可以使用商店中的密码。
  • 选择必要的帐户以进入某些站点。
  • 允许您使用在另一台设备上的一台设备上输入的登录名/密码。

凭据管理API的常见实现示例是Google的密码管理器:passwords.google.com

开放式认证倡议(OATH)


宣誓资源

基于OAuth 2.0的协议的完整列表



All Articles