【问题标题】:How to get access token for web api from native app in other tenant?如何从其他租户的本机应用程序获取 Web api 的访问令牌?
【发布时间】:2017-04-27 05:34:31
【问题描述】:

我创建了一个运行良好的多租户 Web API。现在我想构建一个本地客户端进行测试。 Web API 应用程序在一个租户 (webapitenant) 中定义。测试应用是在另一个租户 (clienttenant) 中定义的,该租户已授予管理员对 Web API 的同意。

我已在 Web API 的应用清单中将 testClientId 添加为 knownClientApplication 并启用了 oauth2AllowImplicitFlow。测试客户端已被授予对 Web API 应用的权限。

获取访问令牌:

var userCredential = new UserCredential("admin@clienttenant.onmicrosoft.com", "password");
var context = new AuthenticationContext("https://login.windows.net/common");

return context.AcquireToken("https://webapitenant.onmicrosoft.com/webApiResourceUri", testClientId, userCredential).AccessToken;

抛出异常: 'Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException' in Microsoft.IdentityModel.Clients.ActiveDirectory.dll

其他信息:
AADSTS65001: The user or administrator has not consented to use the application with ID 'nativeclientid'. Send an interactive authorization request for this user and resource.

抛出异常: 'Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException' in Microsoft.IdentityModel.Clients.ActiveDirectory.dll

其他信息:
AADSTS65001: The user or administrator has not consented to use the application with ID nativeclientid. Send an interactive authorization request for this user and resource.

更新 我创建了一个虚拟控制台应用程序来强制提交我可以接受的同意书。 ADAL 现在返回令牌,但我的 Web API 拒绝它们(状态 401)。

var parameters = new PlatformParameters(PromptBehavior.Always);
var context = new AuthenticationContext("https://login.windows.net/common");
var token = context.AcquireTokenAsync
    ("https://webapi.onmicrosoft.com/appuri", 
    "testappid", 
    new Uri("https://webapi.azurewebsites.net"), parameters).Result.AccessToken;

Console.WriteLine(token); //Output: oauth token

var client = new HttpClient
{
    BaseAddress = new Uri("https://webapi.azurewebsites.net/api/")
};

client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

var response = client.GetAsync("tenants").Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
// Output: {"$type":"System.Web.Http.HttpError, System.Web.Http","Message":"Authorization has been denied for this request."}

【问题讨论】:

    标签: oauth-2.0 azure-active-directory multi-tenant adal


    【解决方案1】:

    请确保网络应用忽略问题验证并且受众与您为访问令牌和此值获取的资源(https://webapi.onmicrosoft.com/appuri", "testappid)相同应该是 App ID URI,您可以在 old Azure portal 上找到它,如下图:

    这里是设置多租户Web API认证的相关代码:

    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
                    new WindowsAzureActiveDirectoryBearerAuthenticationOptions
                    {
                        Audience = ConfigurationManager.AppSettings["ida:Audience"],
                        Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                         TokenValidationParameters= new System.IdentityModel.Tokens.TokenValidationParameters {
                             ValidateIssuer=false
                         }
                    });
    

    【讨论】:

    • 我的应用是这样配置的。我只能通过创建控制台应用程序并使用 PromptBehaviour.Always 来使我的代码正常工作。接受该应用程序后,我的集成测试开始从测试资源管理器工作,因为它使用与控制台应用程序相同的本机应用程序。有没有办法避免这种情况?显然,Visual Studio 测试运行者无法出示同意书。
    • 您的意思是令牌已经适用于 Web API 吗?如果我正确理解您有关于使用测试运行程序测试受 Azure AD 保护的 Web API 的问题,我建议您重新打开一个新线程,以便其他社区可以轻松识别此问题并获得有用的答案。
    • 我根据我目前的发现和您的 cmets 创建了一个新问题。谢谢您的帮助。 stackoverflow.com/questions/41146893/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 2017-04-11
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    相关资源
    最近更新 更多