【问题标题】:Unable to get bearer token from Azure AD to use with API App无法从 Azure AD 获取不记名令牌以与 API 应用程序一起使用
【发布时间】:2015-12-11 21:17:09
【问题描述】:

我有一个 MVC 应用程序需要访问受 Azure AD 身份验证保护的 Azure 中的私有 API 应用程序。所以我需要获取 Azure AD 不记名令牌,将其传输到Zumo-Auth 令牌并使用它来访问 API 应用程序。

我正在检查this tutorial,一切正常,直到我需要从authContext 请求令牌。这是一段代码的sn-p:

var authContext = new AuthenticationContext(
    "https://login.microsoftonline.com/MyADDomain.onmicrosoft.com");

ClientCredential credential = new ClientCredential(
    "04472E33-2638-FAKE-GUID-F826AF4928DB", 
    "OMYAPIKEY1x3BLAHEMMEHEHEHEHEeYSOMETHINGRc=");

// Get the AAD token.
var appIdUri = 
    "https://MyAppGateway-814485545465FAKE4d5a4532cd.azurewebsites.net/login/aad";

//var appIdUri = "https://MyADDomain.onmicrosoft.com/MyAppName";
//var appIdUri = "https://MyADDomain.onmicrosoft.com/";
//var appIdUri = "https://graph.windows.net";

AuthenticationResult result = 
    authContext.AcquireToken(appIdUri, credential); // <-- can't get the token from AD

// downhill from here
var aadToken = new JObject();
aadToken["access_token"] = result.AccessToken;
var appServiceClient = new AppServiceClient(
    "https://MyAppGateway-814485545465FAKE4d5a4532cd.azurewebsites.net/");

// Send the AAD token to the gateway and get a Zumo token
var appServiceUser = await appServiceClient.LoginAsync("aad", aadToken);

带有authContext.AcquireToken(appIdUri, credential) 的行是引起麻烦的行。

如果appIdUri我给https://MyAppGateway-814485545465FAKE4d5a4532cd.azurewebsites.net/login/aad,我得到异常:

400:AdalServiceException:AADSTS50001:资源“https://MyAppGateway-814485545465FAKE4d5a4532cd.azurewebsites.net/login/aad”未为该帐户注册。

但是这条确切的行在 AD 应用程序的 Reply Url 列表中

当我尝试将https://MyADDomain.onmicrosoft.com/MyAppNamehttps://MyADDomain.onmicrosoft.com/ 用作appIdUri 时,我收到一条不同的异常消息:

400:AdalServiceException:AADSTS50105:应用程序“04472E33-2638-FAKE-GUID-F826AF4928DB”未分配给应用程序“https://MyADDomain.onmicrosoft.com/MyAppName”的角色

或者

400:AdalServiceException:AADSTS50105:应用程序“04472E33-2638-FAKE-GUID-F826AF4928DB”未分配给应用程序“https://MyADDomain.onmicrosoft.com/”的角色

在这两种情况下,我都将 AD 应用程序中的 App ID URI 设置为“https://MyADDomain.onmicrosoft.com/MyAppName”或“https://MyADDomain.onmicrosoft.com/”。以及Reply URL 列表中的两个名称。

最终经过足够的尝试,我将https://graph.windows.net 设置为appIdUri 并取回了不记名令牌。但是令牌的有效期是过去的(大约过去 1 分钟)。所以我对此无能为力。并在尝试使用令牌登录 API 应用程序时得到401-Unauthenticated

我错过了什么?

【问题讨论】:

  • 什么是Zumo-Auth 令牌?它与您的问题有多相关?
  • @ShaunLuttin Zumo-Auth 是 Azure 中的 ApiApp 和移动应用程序用于身份验证的令牌。我需要它来通过 ApiApp 进行身份验证。我想这个问题并不重要,因为我似乎无法获得不记名令牌,这是之前的一步。
  • 您可以通过浏览器登录吗? IE。您可以通过浏览器完成此步骤:azure.microsoft.com/en-us/documentation/articles/…
  • 是的,通过浏览器登录没有问题 - 要求我输入 MS 密码并让我使用 API。虽然现在不确定——我在实验过程中改变了很多,我可能已经打破了这一点。我会在回到办公室时仔细检查。感谢这个指针 - 仔细检查这并没有出现在我的脑海中。
  • 好吧,如果这行得通,那么我现在的答案可能会。

标签: c# azure azure-active-directory azure-ad-graph-api azure-api-apps


【解决方案1】:

我已经按照您提到的教程进行操作:Call an Azure API app from a web app client authenticated by Azure Active Directory

  1. 创建一个返回联系人数据的 Azure API Api
  2. 将 API 应用部署到 Azure 应用服务。
  3. 使用 Azure Active Directory 保护 API 应用程序。

然后我能够检索到令牌,正如您从以下演示中看到的那样,我的代码与您的代码没有什么不同,只是它使用了使用 Asyncusing Microsoft.IdentityModel.Clients.ActiveDirectory 库的更高版本。

从 AAD 获取访问令牌

class Program
{
    static void Main(string[] args)
    {
        var authContext = new AuthenticationContext(Constants.AUTHORITY);
        var credential = 
            new ClientCredential(Constants.CLIENT_ID, Constants.CLIENT_SECRET);
        var result = (AuthenticationResult)authContext
            .AcquireTokenAsync(Constants.API_ID_URL, credential)
            .Result;
        var token = result.AccessToken;
        Console.WriteLine(token.ToString());
        Console.ReadLine();
    }
}

常量

AUTHORITY。第一段是https://login.microsoftonline.com。最后一部分是允许的租户。我们在 portal.azure.com 上设置了允许的租户,转到我们的应用程序的网关,然后选择设置 > 身份 > Azure Active Directory > 允许的租户。我的租户是 bigfontoutlook.onmicrosoft.com。

CLIENT_ID。我们从添加到 Azure Active Directory 的应用程序中检索此客户端 ID。在 manage.windowsazure.com > Active Directory > 您的目录 > 应用程序 > 您的应用程序 > 配置中找到它。一旦我们检索到它,我们必须将它添加到我们网关的客户端 ID 字段中的 Azure Active Directory 设置中。

CLIENT_SECRET。我们在检索客户 ID 的同一位置创建/检索它。

API_ID_URL。我们通过选择设置 > 身份 > Azure Active Directory > 应用 URL 在网关刀片中为我们的 Web API 应用检索此信息。

以下是适合我的。

class Constants
{
    public const string AUTHORITY =
     "https://login.microsoftonline.com/bigfontoutlook.onmicrosoft.com/";

    public const string CLIENT_ID = 
      "0d7dce06-c3e3-441f-89a7-f828e210ff6d";

    public const string CLIENT_SECRET =
      "AtRMr+Rijrgod4b9Q34i/UILldyJ2VO6n2jswkcVNDs=";

    public const string API_ID_URL = 
      "https://mvp201514929cfaaf694.azurewebsites.net/login/aad";
}

最终解码的 JWT

这是解码后的 JWT 访问令牌所包含的内容。

{
 typ: "JWT",
 alg: "RS256",
 x5t: "MnC_VZcATfM5pOYiJHMba9goEKY",
 kid: "MnC_VZcATfM5pOYiJHMba9goEKY"
}.
{
 aud: "https://mvp201514929cfc350148cfa5c9b24a7daaf694.azurewebsites.net/login/aad",
 iss: "https://sts.windows.net/0252f597-5d7e-4722-bafa-0b26f37dc14f/",
 iat: 1442346927,
 nbf: 1442346927,
 exp: 1442350827,
 ver: "1.0",
 tid: "0252f597-5d7e-4722-bafa-0b26f37dc14f",
 oid: "5a6f33eb-b622-4996-8a6a-600dce355389",
 sub: "5a6f33eb-b622-4996-8a6a-600dce355389",
 idp: "https://sts.windows.net/0252f597-5d7e-4722-bafa-0b26f37dc14f/",
 appid: "0d7dce06-c3e3-441f-89a7-f828e210ff6d",
 appidacr: "1"
}.

注意:它是一次性活动目录帐户中的一次性应用程序,带有一次性资源组,因此显示我的安全凭据不是问题。

图表只是为了确定:)

【讨论】:

  • 谢谢你,我明天试试。
  • 你知道吗?我复制了你的代码,放了我的指导、秘密和网址。又得到了同样的该死的例外!然后我创建了一个全新的 Api 应用程序和一个新的 AD 应用程序。复制凭据,一切正常。不知道到底是什么坏了,但我怀疑 AD 应用程序被搞得面目全非。
  • 是的。有时故障排除会造成混乱:)
  • 我只想补充一点,我遇到了完全相同的问题,错误完全相同,解决方案完全相同(重新开始并重试)。问题是,我现在重新开始并再次尝试了大约 8 次,但 8 次中只有 5 次成功了。这似乎有些不可靠 - 我不知道这是由于工具的预览性还是什么,但它似乎并不是非常可靠。 :-/
  • @Jaxidian 我曾经在使用 OAuth 时遇到过类似的情况,结果证明这是使用 HTTP 和 HTTPS 之间的区别。你检查过吗?
猜你喜欢
  • 2017-03-10
  • 2019-06-16
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
相关资源
最近更新 更多