2016-10-28 37 views
1

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

error message

通过这一点,我们已经获准进入该应用的单点登录和AAD读取目录数据。 (编辑:我们通过手动继provisioning_ticket_URL是由Auth0 API调用返回创建Connection对象对象的一部分做这个网址提示我们选择Azure的凭据,然后显示此页: grantaccess

直到我们通过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 from:

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

into keyID and value,respe沉着应对。我已经在其他地方看过,值应该是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调用确实正在改变应用的显示名称。可悲的是,似乎这些编辑没有解决问题,我仍然得到原始错误。

我们创建这样的图形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" 
     } 
     ] 
    } 
    ] 
} 
+1

尝试更改只显示名称,并保存应用程序(无需创建一个新的密钥)。这是否也解决了这个问题?你能分享你用来在Azure AD中创建对象的代码吗?你提到你已经“授予”应用登录和阅读目录的权限 - 你是如何做到这一点的? –

+0

@PhilippeSignoret感谢您花时间回复,Philippe。我已经更新了相应的问题 - 请参阅上面编辑的部分。 – MGS

回答

2

看起来这里的最终问题与应用程序同意有关。 我将进入更多的细节在这里,但随时通过这个文件,该文件描述了我们同意框架迅速采取读: https://azure.microsoft.com/en-us/documentation/articles/active-directory-integrating-applications/

你是显示在您的应用程序清单的东西都涉及到你的应用程序的配置,但是,您的应用程序的同意记录将不会在那里找到,因此我认为您的'a/b'测试不会有收获。

我想你在这里真正发现的是,如果你是管理员并保存应用程序,Azure门户在后台会有一些“魔术”,它会同意你的应用程序。当您在门户网站中开始注册应用程序(再次以管理员身份注册)时,我们会在您保存应用程序后自动为您记录同意书。这种情况发生在后台,产生的“对象”是:租户中的应用程序的服务主体,以及您作为用户和服务主体之间的同意链接。创建的链接具体为“管理员租户范围的同意”对象,如果您将“prompt = admin_consent”作为查询字符串添加到您的登录网址,您将得到同样的结果。

当您使用其他方法(如Graph API或AAD PowerShell)创建应用程序时,不会创建这些对象,这会导致您在尝试和验证时看到的那种错误。

这里的解决方案是,您需要拥有与租户的管理员一次的交互式登录体验,然后才能让其他人登录到该应用程序。在此登录体验期间,您必须获得管理员同意您的应用程序及其所需的权限。在获得了一次同意的经历之后,以后对你申请的电话不需要同意,你也不会遇到你遇到的问题。

因此,在总结:

  1. 使用你想
  2. 然后使用你的应用程序信息的任何方法自动创建一个应用程序,并创建一个管理员交互式登录,使用查询字符串“提示= admin_consent”
  3. 然后使用你的应用程序,但是你期望它的工作

谢谢! Shawn Tabrizi

相关问题