繁体   English   中英

自动创建Azure AD Web应用程序密钥

[英]Automating creation of an Azure AD Web App Key

我们编写了一组Powershell脚本,以自动化在Azure环境中创建Web应用程序新实例的过程。 这些脚本的一部分使用Graph API创建了一些Azure AD对象以及Auth0中的相应对象,我们将它们用于单点登录。 到目前为止,我们还没有成功以编程方式为AAD应用程序创建新密钥。 我们已经尝试了多种方法,虽然我们可以看到生成的应用程序确实具有适当的密钥(并且Auth0中的连接对象在其“客户机密”字段中具有该密钥),但是当尝试进行身份验证时,我们总是会收到此错误:

错误信息

至此,我们已经授予访问该应用程序的权限以进行单点登录和读取AAD中的目录数据。 (编辑:我们通过手动遵循Provisioning_ticket_URL来执行此操作,该URL是Auth0 API调用返回的对象的一部分,以创建Connection对象。此URL提示我们输入Azure凭据,然后显示此页面: 授予访问权限

该错误一直存在,直到我们通过Azure门户为应用程序手动创建新密钥,保存应用程序并将新创建的密钥复制到Auth0连接中为止。 这样做总是可以解决问题,但我们希望避免执行此额外步骤。

在我们通过API调用创建的AAD应用程序主体中,我们有以下部分定义密钥:

"passwordCredentials": 
  [
    {
        "startDate":  "2016-10-28T20:40:32Z",
        "endDate":  "2017-10-29T20:40:32Z",
        "keyId":  "(a GUID)",
        "value":  "(a Base64 string)"
    }
  ],

至于这些值,我们尝试以多种不同的方式生成它们,并且它接受API PUT调用中的值,但是当我们尝试登录时,它们仍然给我们同样的错误。例如,我们尝试的一种方法是从中插入$ appKeyGUID和$ appKeyValue中的值:

$appKeyGUID = [guid]::NewGuid() 
$guidBytes = [System.Text.Encoding]::UTF8.GetBytes($appKeyGUID)
$appKeyValue = [System.Convert]::ToBase64String($guidBytes);

分别放入keyID和value中。 我在其他地方读过,该值应为44个字符长,而这个字符将不是。

但是似乎价值本身可能不是问题。 我尝试过通过Azure门户生成密钥,使用Graph API GET调用检索keyId,然后将这两个确切值硬编码到应用程序主体中,但是登录仍然会产生相同的错误。

知道我哪里出错了吗?

编辑:根据Philippe的建议,我尝试通过门户仅更改AD应用程序的显示名称,这确实解决了问题。 这使我认为,通过门户进行保存时,已修复的应用程序正文中其他地方可能有问题。 我在进行手动保存之前和之后检查了清单,确实确实有一个小的区别:在RequiredResourceAccess部分中(我从这里中学到了这一点http://www.cloudidentity.com/blog/2015/09/01/azure -ad-permissions-summary-table / ,在这里https://www.microsoftpressstore.com/articles/article.aspx?p=2473127&seqNum=2 ),我有以下内容:

{
  "id": "5778995a-e1bf-45b8-affa-663a9f3f4d04",
  "type": "Role"
},
{
  "id": "5778995a-e1bf-45b8-affa-663a9f3f4d04",
  "type": "Scope"
}

与此相反,门户网站将其更改为

{
  "id": "5778995a-e1bf-45b8-affa-663a9f3f4d04",
  "type": "Role,Scope"
},

因此,我更改了要发送的正文以匹配第二种格式。 不幸的是,由于此更改,我们仍然遇到相同的错误。 此外,我验证了清单在门户网站上进行保存之前和之后是否相同,以及应用程序上的API GET调用返回的正文。 必须有别的 ,门户保存正在发生变化比应用程序的定义等。

之后,我尝试使用Graph API执行两次PATCH调用,以将显示名称更新为某种名称,然后将其更改回原来的名称,希望它的行为类似于通过门户进行操作并解决问题。 我通过门户网站验证了PATCH调用确实在更改应用程序的显示名称。 可悲的是,这些修改似乎无法解决问题,而我仍然遇到了原始错误。

我们使用Graph API调用创建应用程序,如下所示:

$uri = "https://graph.windows.net/$waadTenant/applications?api-version=1.6"
$newADApp = (Invoke-RestMethod –Uri $uri –Headers $authHeader –Method POST -Body $newappbody –Verbose)

这是我们最终用来定义应用程序的$ newappbody。 为了进行故障排除,我保留了一些硬编码的内容:

{
  "odata.type": "Microsoft.DirectoryServices.Application",
  "displayName": "customer1",
  "homepage": "https://customer1.(our tenant).com",
  "identifierUris":
  [
    "https://customer1.(our tenant).com"
  ],
  "replyUrls":
  [
    "https://(our tenant).auth0.com/login/callback"
  ],
  "passwordCredentials":
  [
    {
        "startDate":  "(a hardcoded date)",
        "endDate":  "(a hardcoded date)",
        "keyId":  "(hardcoded GUID that was previously generated by the portal and extracted through an API GET)",
        "value":  "(hardcoded Base64 like above)"
    }
  ],
  "requiredResourceAccess":
  [
    {
      "resourceAppId": "00000002-0000-0000-c000-000000000000",
      "resourceAccess":
      [
        {
          "id": "5778995a-e1bf-45b8-affa-663a9f3f4d04",
          "type": "Role,Scope"
        },
        {
          "id": "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
          "type": "Scope"
        },
        {
          "id": "6234d376-f627-4f0f-90e0-dff25c5211a3",
          "type": "Scope"
        }
      ]
    }
  ]
}

似乎这里的最终问题与应用程序同意有关。 我将在此处进行详细介绍,但可以随时快速通读本文档,该文档描述了我们的同意框架: https : //azure.microsoft.com/zh-cn/documentation/articles/active-directory-integrating-applications /

您在“应用程序清单”中显示的内容与您的应用程序配置有关,但是,在此处找不到您的应用程序的同意记录,因此,我认为您的“ a / b”测试不会有成果。

我认为您在这里真正发现的是,Azure门户在后台有一些“魔术”,如果您是管理员并且保存了该应用程序,则该许可将同意您的应用程序。 当您从头到尾在门户中再次注册应用程序(再次以管理员身份)时,一旦您保存了应用程序,我们就会自动为您记录同意。 这是在后台发生的,创建的结果“对象”是:租户中您的应用程序的服务主体,以及您作为用户和服务主体之间的同意链接。 创建的链接专门是“管理员租户范围内的同意”对象,如果将“ prompt = admin_consent”作为查询字符串添加到登录URL中,则将获得相同的结果。

当您使用其他方法(例如Graph API或AAD PowerShell)创建应用程序时,不会创建这些对象,这将导致您尝试进行身份验证时看到的错误类型。

这里的解决方案是,您需要与租户的管理员一起具有一次交互式登录体验,然后才能使其他人登录该应用程序。 在这种登录体验期间,您必须获得应用程序的管理员同意以及所需的权限。 经过这一次的同意经历,以后对您的应用程序的调用/从您的应用程序进行的调用无需征得您的同意,并且您也不会遇到所遇到的问题。

因此,总而言之:

  1. 使用所需的任何方法自动创建应用
  2. 然后使用您的应用程序信息,并使用查询字符串“ prompt = admin_consent”与管理员创建交互式登录。
  3. 然后使用您的应用程序,但是您希望它能正常工作

谢谢! 肖恩·塔布里兹(Shawn Tabrizi)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM