如何为多个Web API提供授权方法

Azure活动目录(Active Directory,Azure AD)是一种业界比较流行的企业级身份认证服务。如今,许多组织都在使用该服务,来启用应用程序的单点登录(SSO),并保护其提供的Web API。其中,基于OpenId Connect(OIDC)身份验证的Microsoft Identity Platform 2.0是针对OAuth 2.0授权流程的最新改进版本。


如何为多个Web API提供授权方法


如果您的应用程序使用到了Azure AD的如下功能,那么本文正好向您介绍如何为多个Web API提供授权的方法:

1. 启用单点登录(OpenId Connect身份验证)。

2. 使用OAuth 2授权(隐式授权流程)保护Web API。

3. 单个客户端应用程序使用到了多个Web API提供程序。

首先,我们假设您的客户端应用程序属于单页面式架构(Single Page Architecture,如:Angular SPA),而且该架构使用到了如下两个不同的API:

1. Microsoft Graph API(https://dzone.com/articles/getting-access-token-for-microsoft-graph-using-oau?preview=true) - 获取员工个人资料的详细信息,并将其显示在应用程序的GUI中。该过程需要获取一个访问令牌,并通过Graph API的调用进行提交。

2. 自定义的Web API – 服务于应用程序的基本功能和数据。对于每个Web API的调用,都必须获得并提交不同的且单独的访问令牌。

显然,应用程序的用户必须事先使用Azure AD来进行身份验证(OIDC,https://dzone.com/articles/integrating-okta-oauth-20-oidc-with-mulesoft-anypo),然后才能访问受API保护的各项功能与数据。也就是说,它们需要传递有效的JWT访问令牌,之后才能访问到受保护的API。

在Azure Portal中执行SPA应用程序的注册

第一步,在Azure portal(https://portal.azure.com/#home)中注册您的客户端应用程序(SPA)。注意:请为您的SPA应用设置重定向的URI,并为隐式授权的OAuth 2数据流,选择ID令牌和Access令牌。下图是某个假定Web应用程序的屏幕截图,可供您参考:

如何为多个Web API提供授权方法

指定URI路由

在Azure Portal中公布Web API

为Web API定义如下的配置。

1. 为Web API自定义范围,以控制其访问受API保护的功能。

2. 授权可以调用Web API的客户端应用程序,以实现在调用期间无需人工判断是否同意。

如何为多个Web API提供授权方法

公布API

在Azure Portal中为客户端应用程序指定API的权限

为客户端应用程序选择调用API的所有权限。如果需要获取用户的配置文件,请选择带有User.Read的Microsoft Graph API。如下图截屏所示:

如何为多个Web API提供授权方法

请求Microsoft Graph API权限

用同样的方法,选择Web API、以及自定义API的权限范围。

如何为多个Web API提供授权方法

请求Web API权限

从Angular SPA中调用Microsoft Graph API

我们所假设的Angular SPA(https://dzone.com/articles/angular-tutorials-and-articles)会通过调用Graph API,来获取用户个人资料的详细信息。当然,您也可以在Angular应用中使用任何一种身份验证的客户端库,例如:

  • angular-auth-oidc-client
  • oidc-client

此处值得特别注意的是:Microsoft Graph API和自定义的Web API是两个截然不同的API提供类型,因此它们的作用域是无法被组合到同一个Angular应用内的同一个Azure AD进行授权调用的。那么,正确的方法应该是:使用两个单独的调用。即:分别对Microsoft Graph API和Web API各调用一次,并为每个调用指定不同的范围。

下面是调用Microsoft Graph API的具体顺序与步骤:

  1. 针对从Angular到Azure AD OAuth 2.0授权端点的首次调用,指定User.Read的范围。

如何为多个Web API提供授权方法

指定User.Read的范围

2. Azure AD执行用户的身份验证。

3. Azure AD生成访问令牌,该访问令牌能够基于用户配置文件的详细信息,来调用Graph API的对应权限。同时,它还会生成一个ID令牌,以指示用户进行登录。

4. 注意:在v2.0中,Azure AD通过内部调用userinfo Graph API,所获取和返回的用户详细信息,仅为基本的用户属性。后续,我们可以显式地调用另一个Graph API端点,以获取用户的详细属性信息。

5. 在Azure AD的重定向请求中,我们将基于Angular代码,获取对应的访问令牌。通过调用Graph API,我们将此令牌的授权标头(Authorization header)设置为Bearer类型的令牌。据此,API将返回用户个人资料的详细信息,包括:员工编号、照片和组织架构等。

如下示例是一个对于Graph API端点的HTTP GET请求,它能够获取用户的员工编号。注意:Bearer类型的令牌应当在请求的授权标头被传递过去。

https://graph.microsoft.com/v1.0/me$,userPrincipalName,country,extension_8b4e685f580748b59864d62c2e7fcfad_employeeNumber

从Angular SPA中调用自定义的Web API

具体顺序与步骤如下:

1. 指定http://mystatementapi/access_as_user的范围(虽然可以是任意范围,但是我们最好去匹配那些Azure AD portal中的应用程序,在其注册过程中所定义好的范围)。该范围将被用于第二次调用Azure AD OAuth 2.0的授权端点。

如何为多个Web API提供授权方法

指定user_as_access的范围

2. 注意:由于在先前的调用中,我们的浏览器已经设置好了身份验证的cookie,因此这一步将不再执行用户的身份验证。

3. Azure AD生成另一个具有访问权限的访问令牌,用以调用Web API。该令牌将被用于每一个Web API。

4. 在Azure AD重定向的请求中,我们将基于Angular代码,获取对应的访问令牌。通过调用自定义的API,我们将此令牌的授权标头(Authorization header)设置为Bearer类型的令牌。

5. Web API验证来自Azure AD的令牌,如果验证成功,则返回正常的响应信息;如果失败,则告知有关错误的信息。

刷新访问令牌

通常情况下,访问令牌的有效期是短暂的。我们可以将令牌的过期时间配置为一个小时或更短。那么在令牌到期之前,客户端应用程序应当从Azure AD处请求新的访问令牌。而且,该过程应当在没有用户干预的情况,由后台自动完成。因此,我们可以在客户端应用程序中采用隐藏的iframe方法。

实际上,这对于用于调用那些自定义Web API的访问令牌来说(而不是本示例前面提到的Graph API)显然是必需的。

总结

上文提到的Azure AD充当了基于云端身份认证服务的角色,您完全可以将自己的应用部署到其他的云服务、或本地数据中心中,以实现个性化的身份验证与授权。当然,在开始编写Angular应用程序代码之前,您也可以使用Postman客户端(译者注:一款强大的网页调试和接口测试工具)来测试和验证Azure AD的配置、以及各种Web API。

总的说来,通过上述详细的设计方法和实现步骤,我们演示了Angular客户端应用程序如何从不同的Web API处获取OAuth 2类型授权的过程。希望对您有所帮助。

您可能还会对下面的文章感兴趣: