我可以使用Azure B2C来获取ID令牌*和*获取针对Azure部署的服务的访问令牌吗?

Tho*_*urg 5 openid azure adal openid-connect azure-ad-b2c

我只能弄清楚如何使用B2C获取ID令牌-但随后我失去了常规AAD应用程序的所有好处(特别是访问令牌,范围和用户同意)

下面,我将描述一个简化的方案以及我尝试过的方案。

情境

想象一下,我正在开发一个客户端(javascript SPA)和两个服务(WebAPI):

在此处输入图片说明

  • A是基于WebAPI的服务,具有两个范围(ReadA和WriteA),已在Azure中注册和托管
  • B是另一种基于WebAPI的服务,具有两个范围(ReadB和WriteB),已在Azure中注册和托管
  • C是Javascript SPA

现在,我希望用户使用Azure B2C登录,这种方式可以使我的客户端C产生以下令牌:

  • 一个id令牌,因此客户端C可以按名称向我寻址
  • 一个访问令牌具有范围ReadA和WriteA的服务A(在通常的用户同意之后发布)
  • 具有范围ReadB的服务B 的访问令牌(在通常的用户同意之后发布)

能做到吗?如何?有任何例子吗?

我已经找到的所有示例都显示了一个客户端对用户进行身份验证,还有一些示例显示了如何获取单个访问令牌(不支持范围)

我尝试过的沙发

我的实验者已经使用

为避免与客户端库有关的混乱,下面将根据Fiddler的报告,以发送和接收的请求和响应来描述我的实验。

单个客户端-仅ID令牌

这是基准方案,由我发现的大多数使用方法展示。

客户端C向B2C发送以下请求:

https://login.microsoftonline.com/fooplanner.onmicrosoft.com/oauth2/v2.0/authorize?
   p=b2c_1_fooplanner-signuporsignin&
   client_id=ffffffff-ffff-ffff-ffff-ffffffffffff&
   response_type=id_token&
   scope=openid email profile
Run Code Online (Sandbox Code Playgroud)

在提示我输入我的凭据后,B2C然后最终返回一个id_tokenuuu...B2C中我的用户条目的GUID):

id-token:
{
  "ver": "1.0",
  "iss": "https://login.microsoftonline.com/08de3e5f-6a10-4d7c-a0e3-fc4a627a712b/v2.0/",
  "sub": "uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu",
  "aud": "ffffffff-ffff-ffff-ffff-ffffffffffff",
  "oid": "uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu",
  "name": "Thomas"
  "tfp": "B2C_1_fooplanner-signuporsignin"
}
Run Code Online (Sandbox Code Playgroud)

(为简便起见,我省略了所有OAuth2重定向,Base64 JWT解码等。-我什至从令牌中省略了时间戳,随机数等。如果它们相关,我可以提供完整的详细信息)

oidc-client.js可以按预期方式接收和处理此消息:我最终得到一个ID令牌,而没有访问令牌。

单个客户端-ID令牌+访问令牌

经过一番挖掘之后,我也找到了一种获取访问令牌的方法:在范围内包含B2C应用程序ID,并询问tokenid_token响应类型。

在此变体中,客户端C向B2C发送以下请求:

https://login.microsoftonline.com/fooplanner.onmicrosoft.com/oauth2/v2.0/authorize?
   p=b2c_1_fooplanner-signuporsignin&
   client_id=ffffffff-ffff-ffff-ffff-ffffffffffff&
   response_type=token id_token&
   scope=openid email profile ffffffff-ffff-ffff-ffff-ffffffffffff
Run Code Online (Sandbox Code Playgroud)

然后B2C最终返回an id_token an access_token

id_token:
{
  "ver": "1.0",
  "iss": "https://login.microsoftonline.com/08de3e5f-6a10-4d7c-a0e3-fc4a627a712b/v2.0/",
  "sub": "uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu",
  "aud": "ffffffff-ffff-ffff-ffff-ffffffffffff",
  "oid": "uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu",
  "name": "Thomas"
  "tfp": "B2C_1_fooplanner-signuporsignin"
}

access_token: 
{
  "iss": "https://login.microsoftonline.com/08de3e5f-6a10-4d7c-a0e3-fc4a627a712b/v2.0/",
  "aud": "ffffffff-ffff-ffff-ffff-ffffffffffff",
  "oid": "uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu",
  "sub": "uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu",
  "name": "Thomas",
  "tfp": "B2C_1_fooplanner-signuporsignin",
}
Run Code Online (Sandbox Code Playgroud)

oidc-client.js再次按预期方式接收和处理了该消息:我最终得到了ID令牌和访问令牌。

但是请注意,这两个令牌有多么可疑-但是,我再次要求B2C应用程序而不是正确注册(AAD)应用程序的访问令牌。

单客户,单服务

所以我想:让我们遵循以前的方法-仅这次,请求两个真实服务之一的访问令牌。

请求:

https://login.microsoftonline.com/fooplanner.onmicrosoft.com/oauth2/v2.0/authorize?
   p=b2c_1_fooplanner-signuporsignin&
   client_id=ffffffff-ffff-ffff-ffff-ffffffffffff&
   response_type=token id_token&
   scope=openid email profile aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
Run Code Online (Sandbox Code Playgroud)

但是,这抱怨范围未知(aaa...)-因此我滥用了协议,或者B2C不了解常规的AAD应用程序(请注意,在同一租户中)。

推测:使用授权端点?

我读的地方(在OpenID的规范呢?)那了IDP(即B2C)具有授权的端点,可以用来交换的id_token一个access_token

这是解决这个问题的方法吗?那里有客户端库支持吗?

Fei*_*SFT 0

我能够按照您的描述重现该问题(the scope ... is not supported)。

据调查,B2C应用目前不支持从其他应用获取访问令牌。我们无法向 B2C 应用程序授予其他应用程序的权限。

在您的场景中使用客户端凭据流程而不是授权代码授予流程是否有帮助?如果是,我们可以在 B2C 租户处从 Azure 经典门户注册另一个应用程序,并授予该应用程序的 Web API 权限。然后我们可以使用下面的请求来获取令牌,而无需用户登录:

POST:https://login.microsoftonline.com/{tenantId}/oauth2/token

resource={appIdURI of web API}&client_id={clientId}&client_secret={client_secret}&grant_type=client_credentials
Run Code Online (Sandbox Code Playgroud)

然后我们就可以像下面这样获取token:

在此输入图像描述

以下是清单更改以添加应用程序权限:

 "appRoles": [
        {
          "allowedMemberTypes":["Application"],
          "description":"Allow the application to write EasyAuthB2CAppWebAPI on behalf of the application.",
          "displayName":"Write EasyAuthB2CAppWebAPI",
          "id":"150c93f9-5d1a-4de2-821f-f69e8915dff7",
        "isEnabled":true,
          "value":"writeAppAll"
      },
        {
          "allowedMemberTypes":["Application"],
          "description":"Allow the application to read EasyAuthB2CAppWebAPI on behalf of the application.",
          "displayName":"Read EasyAuthB2CAppWebAPI",
          "id":"250c93f9-5d1a-4de2-821f-f69e8915dff7",
          "isEnabled":true,
          "value":"readAppAll"
      }
  ],
Run Code Online (Sandbox Code Playgroud)

如果您希望Azure B2C应用程序支持获取其他应用程序的访问令牌,您可以尝试从这里提交反馈。