Azure Active Directory v2 - 获取自定义范围 token

标签 azure oauth-2.0 azure-active-directory botframework microsoft-graph-api

我正在学习如何为 OAuth 服务生成 token ,它将在聊天机器人中使用。当我使用下面显示的代码时,我可以成功获取默认范围的 Graph token ,并且该 token 对于 MS Graph API 调用有效。现在,我想要实现的是以类似的方式生成自定义范围 token ,以便调用外部服务(不是 MS Graph API)。该 token 需要具有自定义范围。我尝试将字典参数“范围”更改为为 Azure 中的聊天机器人配置的范围名称,但失败了:

private async Task<string> GetGraphTokenAsync()
    {
        var dict = new Dictionary<string, string>();
        dict.Add("client_id", _graphTokenSettings.ClientId);
        dict.Add("client_secret", _graphTokenSettings.ClientSecret);
        dict.Add("scope", "https://graph.microsoft.com/.default");
        dict.Add("grant_type", "client_credentials");

        string gUrl = $"https://login.microsoftonline.com/{_graphTokenSettings.Tenant}/oauth2/v2.0/token";

        var client = new HttpClient();
        var req = new HttpRequestMessage(HttpMethod.Post, gUrl) { Content = new FormUrlEncodedContent(dict) };

        var httpResponseFromService = await client.SendAsync(req);
        httpResponseFromService.EnsureSuccessStatusCode();

        if (httpResponseFromService.Content is object
            && httpResponseFromService.Content.Headers.ContentType.MediaType == "application/json")
        {
            string stringFromservice = await httpResponseFromService.Content.ReadAsStringAsync();
            JObject tokenresponse = JsonConvert.DeserializeObject<JObject>(stringFromservice);
            string token = tokenresponse["access_token"].Value<string>();
            return token;
        }
        else
        {
            _logger.LogError($"Cannot get token for Microsoft Graph. httpResponseFromService.Content:{httpResponseFromService.Content}" );
            throw new Exception("Cannot get token for Microsoft Graph.");
        }
    }

我的机器人中的提供程序配置如下,它是否用作服务提供程序:Azure Active Directory v2:

enter image description here

这是使用 OAuth 工具生成的自定义 token 的示例(租户 ID 和其他值更改为仅说明数据,但所有这些值在使用时都匹配且正确),它正在调用相同的 url我尝试调用“login.microsoftonline.com”来生成自定义范围 token :

enter image description here

此生成的自定义范围 token 有效。它已在我的租户 Azure 级别配置为“api://botid-GUID/access_as_user”,但我想通过 http 客户端生成它作为我的代码示例。您知道如何使用此自定义范围和类似的 httpClient 方法获取 token 吗?看来我发送的范围参数(“api://botid-GUID/access_as_user”)对于 client_credentials 授予类型调用不正确:

默认范围:

 dict.Add("client_id", _graphTokenSettings.ClientId);
        dict.Add("client_secret", _graphTokenSettings.ClientSecret);
        dict.Add("scope", "https://graph.microsoft.com/.default");
        dict.Add("grant_type", "client_credentials");

替换为:

 dict.Add("client_id", _graphTokenSettings.ClientId);
        dict.Add("client_secret", _graphTokenSettings.ClientSecret);
        dict.Add("scope", "api://botid-GUID/access_as_user");
        dict.Add("grant_type", "client_credentials");

任何帮助将不胜感激。

最佳答案

我尝试在我的环境中重现相同的结果并得到以下结果:

我有一个 Azure AD 应用程序,通过公开 API 创建了一个自定义范围,如下所示:

enter image description here

我注册了另一个名为 ClientApp 的应用程序,并通过授予同意将其添加到自定义范围之上,如下所示:

enter image description here

在我的 Azure 机器人中,我添加了一项与服务提供商的连接设置作为 Azure Active Directory v2,如下所示:

enter image description here

当我运行测试连接时,我成功获得了 token ,如下所示:

enter image description here

当我解码上述 token 时,我得到了范围如下的声明:

enter image description here

当您通过公开 API 创建自定义范围时,它会受到涉及用户交互的委派权限的控制,如下所示:

enter image description here

Note that, client credential flow only works with Application permissions that does not involve user interaction.

您需要创建应用角色,而不是在具有不同唯一值访问权限的应用程序中公开 API-作为用户如下所示:

enter image description here

您可以将上述应用角色添加到应用程序权限下的客户端应用程序中,并确保授予同意,如下所示:

enter image description here

除此之外,客户端凭据授予类型支持在使用 v2 端点时仅以 /.default 结尾的范围。否则,它将抛出异常,如下所示:

enter image description here

解决上述错误,您需要在end处将范围替换为/.default,如下所示生成 token 时:

POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id:appID
grant_type:client_credentials
client_secret:secret
scope: api://87xxxa-6xex-4dxa-9xaf-b1dxxxx9819/.default

回应: enter image description here

当我解码上述 token 时,我得到了具有以下角色的声明:

enter image description here

请注意,解码后的 token 在roles声明中包含Application权限,而在scp 声明。

在您的场景中,如果您想要将自定义范围与客户端凭据授予类型一起使用,则需要创建具有唯一值的应用角色属于应用程序权限。

确保在结束处使用/.default更改范围。

关于Azure Active Directory v2 - 获取自定义范围 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74441243/

相关文章:

azure - 使用 BICEP 更新不同资源组中的 DNS 区域

node.js - 通过 Node.js 通过 Putty 连接 Azure 虚拟机?

azure - Azure API 管理服务中的 "JWT Validation Failed: JWT not present.."

ruby-on-rails - 如何通过网络将字符串从 C 发送到 Ruby on Rails 应用程序?

oauth-2.0 - Azure : Access to https://login. microsoftonline.com/{tenant-id}/saml2 与不记名 token

postgresql - 使用powershell在azure ubuntu虚拟机中安装postgres

azure - 从命令或 API 创建 Azure AD 租户

python - 使用 webapp2 session 的 Google Cloud Endpoints 身份验证

objective-c - 与 azure b2c 获取方案集成的 ios 应用程序没有注册处理程序错误

azure-active-directory - Azure Active Directory B2C 自定义错误页面被忽略