25

使用钩子促进OAth 2.0与OpenID连接

 4 years ago
source link: http://developer.51cto.com/art/202004/614350.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【51CTO.com快译】作为开发人员,您一定听说过OAuth 2.0和OpenID Connect(OIDC)吧?它们是用于向Web应用程序添加身份验证和授权的两款强大工具。

本文将向您展示如何使用Okta的新型内联钩子(请参见-- https://developer.okta.com/docs/reference/api/inline-hooks/ )将信息传递到那些通过OIDC和OAuth获得的令牌中。

首先,您将在Okta中设置OIDC应用程序,以查看返回的令牌类型。然后,您将配置一个Spring Boot API应用。通过各种API端点,您可以向Okta注册令牌钩子,并服务于Okta的令牌patch请求。在操作完成的时候,由于注册了钩子,您会发现有效载荷中的令牌。

在和本文一起动手实践之前,请您事先设置好以下内容:

下面,让我们再来了解一下OIDC和OAuth的相关概念。

使用OAuth 2.0进行委托授权

让我们假想一个场景:诸如Yelp(译者注:美国最大的点评网站)之类的客户端应用从诸如Google之类的认证服务中请求访问令牌。您作为资源所有者使用自己的凭据登录Google,并将您的同意授予Yelp,以便其仅访问自己的联系人。因此,Yelp拥有了访问令牌,可以通过Google的Contacts API请求资源服务器,以获取您的联系人信息。在此过程中,Yelp永远不会看到您的密码,也永远不会访问超出您同意范围之外的内容。并且,您可以随时撤回自己的同意。

使用OpenID Connect进行身份识别

在这个同意和授权环节中,您可以注意到它只缺少一样东西:身份。我们需要引入新的令牌:身份令牌,通过在OAuth 2.0之上的一层--OpenID Connect(OIDC),来验证用户的身份信息,并且以JWT( https://developer.okta.com/docs/api/resources/oidc#access-token )格式被编码到经由密码签名的令牌之中。这样既保证了互操作性,又实现了单点登录(Single Sign On)。

OAuth、以及OIDC扩展使用各种已定义的流(Flows)来管理客户端应用、认证服务器、以及资源服务器之间的交互。如下面的流程所示,我们将重点关注浏览器中的认证代码流(Authorization Code Flow):

  1. 为了访问您的联系人,Yelp通过一个按钮来链接到您的Google通讯录上。
  2. 在单击该按钮后,您将被重定向到Google处,以使用自己的用户名和密码登录。
  3. Google通过显示告知您Yelp希望以只读的方式访问您的联系人。
  4. 一旦您点击同意,Google就会通过浏览器使用临时代码(称为授权代码)重定向回Yelp。
  5. Yelp使用该代码与Google交换访问令牌。
  6. 在完成所有的代码验证之后,Google会向Yelp颁发功能有限(仅对您的联系人有只读的访问权限)的访问令牌。
  7. Yelp将访问令牌提供给Google Contacts API。
  8. Google Contacts API验证该令牌,如果Yelp的请求与令牌标识的功能相匹配,您的联系人列表则会被返回给Yelp。

为OIDC和OAuth 2.0设置Okta Org

下面,您将在Okta中创建一个OpenID Connect应用。

在登录到Okta org后,您可以根据顶层菜单导航至“应用程序”,单击“添加应用”,单击标签为Web的第三个框,然后单击下一步。

EVBnqiq.png!web

JRBz6b3.png!web

最后单击完成。

在Heroku上的OIDC

为了执行各种可用的流程,我创建了一个OIDC playground应用。

在登录到 https://okta-oidc-fun.herokuapp.com 后,您会看到一个带有表单和一些切换按钮的页面。它默认指向的是我的Okta org。当然,您可以通过如下表格将其更改为自己的Okta org。

I3uayiE.png!web

zqiY3yJ.png!web

通过向下滚动并单击链接,您可以启动一个新选项卡,并在其中向Okta org进行身份验证。然后,您将会被重定向回ID令牌和访问令牌的位置。而通过单击“验证ID令牌”,您将可以看到有效载荷已经被编码到了该令牌之中。

至此,您已经了解了Okta中的OpenID Connect应用是如何生成各种令牌的。下面,我们将讨论如何创建一个将自定义声明添加到ID令牌的钩子。由于是发生在对ID令牌进行签名之前,因此您仍然可以安全地对密码签名进行验证。

设置Favorite Beers API

请从GitHub上获取本例的源代码-- https://github.com/oktadeveloper/okta-token-hooks-example

这是一个Spring Boot类型的应用,它使用Okta Spring Boot Starter,来轻松与OpenID Connect和OAuth 2.0相集成。它使用H2( https://www.h2database.com/html/main.html )内存嵌入式数据库和Spring Data JPA( https://spring.io/projects/spring-data-jpa )进行简单的对象关系映射,以及Lombok( https://projectlombok.org/ )项目。该应用程序指向您的Favorite Beers API,以及一个用于处理Okta传入的钩子请求,并返回ID令牌。

在src/main/resources文件夹中,您将看到application.sample.yml文件。您可以通过复制,由它在同一文件夹中产生application.yml文件。接着根据上述提到的设置,自定义application.yml文件的内容,其中包括:issuer、clientId和clientSecret的值。同时,您也可以将id和password值更改为任何其他值。完成这些设置之后,您可以如下命令运行应用程序:

f1bafed45391f2caf537685a568aa6da.png

注意:您需要Java 11或更高的版本,才能运行该示例。如果您使用的是Mac,则建议您使用SDKMAN( https://sdkman.io/ ),来管理Java版本。

操作Beer应用

在应用启动之后,您将看到如下输出,它表明H2内存数据库里已填充了“啤酒”。

3QfQBjf.png!web

现在,您可以使用Beers API来添加自己喜欢的啤酒。不过,所有API端点都受到了OIDC的保护。请执行如下命令,将啤酒添加到收藏夹列表之中:

Fzyqu2z.png!web

如果一切顺利,您将得到如下响应:

iiE77vE.png!web

至此,您已经为该应用程序都创建了一个新的啤酒条目,并将其添加到了自己的收藏夹列表中。

注意:由于该应用程序使用的是内存数据库,因此如果重新启动该应用的话,则需要使用此API重新添加自己喜爱的啤酒。

下面,我们将设置一个内联钩子,将beers声明添加到自己的ID令牌中。

从ID令牌中获取喜爱的啤酒

为了利用钩子来处理API,Okta需要能够通过公共互联网来对其进行调用。在现实生活中,您可以将应用程序部署在某个地方并进行设置,以方便Okta与之交互。而在此出于演示目的,我们将使用ngrok(https://ngrok.com/)服务,来发送一个唯一的、可公共寻址的域,以连接到本地运行的Spring Boot应用上。请在单独的终端上运行如下命令:

AJfArim.png!web

您将看到如下输出:

d60c6b85a2e340741aaf0cf252ca0098.png

请复制其https链接(例如:我所看到的是https://e3fc9a95.ngrok.io),以备后续使用。

设置Okta内联钩子

至此,可公开访问的Spring Boot应用已设置就绪,并可接收Okta的钩子请求了。但是,我们的Okta org尚需进行如下准备:

首先,您需要向Okta注册内联令牌钩子。在Okta org的管理控制台中,请依次进入工作流->内联钩子,单击:添加内联钩子->令牌。请在对应的表单中输入如下内容,并点击“保存”:

Av2YVn3.png!web

其中,Authentication field是Okta用来向钩子提供身份验证的标头。而Authentication secret则是在授权标头中发送的值。

注意:请在application.yml文件中找到身份验证的密钥值。如果钩子ID和密码值发生了改变,那么您需要重新计算基本的身份验证字符串,并将该值反映在上面的设置中。

d1d9da116723efb2982b1ec4fd46f032.png

至此,我们已在自己的Okta org中创建了钩子。如下图所示,Spring Boot应用是通过WebSecurityConfiguration.java在钩子的端点上启用基本身份验证的:

0c011776d83ec6ac516c015d9f0cbf9a.png

基本身份验证被用于/api/hooks/**端点上,而OAuth 2.0则用于其他所有内容。

令牌转换内联钩子的剖析

在配置授权服务器使用钩子之前,让我们先看一下代码的核心。如下代码使用HooksController的方法,可以让ID令牌用您最喜欢的啤酒列表进行patch。

7ZvyAjZ.png!web

TokenHookRequest的类(class)利用Lombok和一些默认的初始化,来确保您不会收到NullPointerException。

Okta会向控制器发送许多令牌钩子的请求。在此,我们仅针对需要的内容使用@JsonIgnoreProperties(ignoreUnknown = true)注释。如您想了解完整的JSON请求示例,请参见-- https://developer.okta.com/docs/reference/token-hook/#sample-json-payload-of-a-request

通过使用请求中的login值,该代码将进行数据库查找,以检索与关联登录的Person。此处Person的记录是我们在将其添加到喜爱啤酒列表时被创建的。

同时,该代码将设置TokenHookResponse,以便通过命令列表来patch ID令牌、并访问aoken。其中,最关键的一行代码是:

Bbe2uin.png!web

它将啤酒名称列表添加到了beers声明所附带的回复之中。如下便是JSON响应:

nyamyay.png!web

而最后一步则是:配置您的授权服务器,以使用该钩子。

将啤酒添加进您的ID令牌

请在顶层菜单中依次点击API->授权服务器->默认->访问策略,向下滚动并点击“默认策略规则”旁的铅笔图标。接着您可以从“使用该内联钩子(Use this inline hook)菜单中,选择“Beers Hook”,并点击“更新规则”。

vUfINr3.png!web

只要您在浏览器中输入localhost:4040,便可看到ngrok的监视界面。

如果回到前面的OIDC playground,您可以关闭带有ID令牌和访问令牌的结果标签。通过再次点击playground上的链接,以及“验证ID令牌”按钮,您将能够看到beers声明、以及已被添加到收藏夹中的任何啤酒。

通过切换回ngrok监视选项卡,您可以看到Okta的请求和Spring Boot应用的响应。

总结

Okta Spring Boot Starter能够使您通过几行代码、以及三个配置属性,将Spring Boot应用与Okta相集成。它不仅能够让Okta的OpenID Connect服务符合相关标准,而且还能为您提供全面的单点登录体验。也就是说,同一用户可以访问许多不同的OIDC应用,而每一个应用都拥有自己的一套要求和配置。最后,请记住:OIDC不能够独立运行,它需要运行在OAuth 2.0之上。OAuth仅专注于授权,而OIDC则添加了身份识别与验证方面的服务。

原文标题:Boost OAuth 2.0 and OpenID Connect Using Hooks,作者:Micah Silverman

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

【责任编辑:庞桂玉 TEL:(010)68476606】


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK