通过Dynamics 365插件的应用服务身份验证访问功能应用

时间:2018-05-23 07:21:12

标签: azure oauth oauth-2.0 azure-functions dynamics-365

我正尝试通过服务到服务调用从Dynamics 365插件访问Azure功能:https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-service-to-service

此功能受应用服务身份验证保护。

我创建了一个功能应用程序并启用了App Service身份验证  在平台功能下 - >认证/授权。 我启用了Azure Active Directory作为Auth Provider,并将Management模式设置为Express

enter image description here

然后,我从高级模式获得了生成的客户端ID和客户端密钥:

enter image description here

显然,基于我需要4个必需参数的文章,这是基于Azure函数的令牌请求所需的全部内容:

客户ID

客户端秘密

授予类型

资源

我发出以下请求以从Dynamics 365插件生成令牌,但出现以下错误:

Invalid Plugin Execution Exception: Microsoft.Xrm.Sdk.InvalidPluginExecutionException: {"error":"invalid_client","error_description":"AADSTS70002: Error validating credentials. AADSTS50012: Invalid client secret is provided.\r\nTrace ID: 06ddda7f-2996-4c9b-ab7e-b685ee933700\r\nCorrelation ID: d582e2f2-91eb-4595-b44b-e95f42f2f071\r\nTimestamp: 2018-05-23 06:30:58Z","error_codes":[70002,50012],"timestamp":"2018-05-23 06:30:58Z","trace_id":"06ddda7f-2996-4c9b-ab7e-b685ee933700","correlation_id":"d582e2f2-91eb-4595-b44b-e95f42f2f071"}-The remote server returned an error: (401) Unauthorized.

我的代码是:

         var tokenendpoint = "https://login.microsoftonline.com/de194c13-5ff7-4085-91c3-ac06fb869f28/oauth2/token";
         var reqstring = "client_id=" + Uri.EscapeDataString("5f315431-e4da-4f68-be77-4e257b1b9295");
         reqstring += "&client_secret=" + Uri.EscapeDataString("/oK7nh8pl+LImBxjm+L7WsQdyILErysOdjpzvA9g9JA=");
         reqstring += "&resource=" + Uri.EscapeUriString("https://keyvaultaccess.azurewebsites.net");
         reqstring += "&grant_type=client_credentials";

         //Token request
         WebRequest req = WebRequest.Create(tokenendpoint);
         req.ContentType = "application/x-www-form-urlencoded";
         req.Method = "POST";
         byte[] bytes = System.Text.Encoding.ASCII.GetBytes(reqstring);
         req.ContentLength = bytes.Length;
         System.IO.Stream os = req.GetRequestStream();
         os.Write(bytes, 0, bytes.Length);
         os.Close();

         //Token response
         HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
         StreamReader tokenreader = new StreamReader(resp.GetResponseStream());
         string responseBody = tokenreader.ReadToEnd();

我已经确定我有正确的客户端密码并且还编码了它,因为我在某处读过'+'和'/'并不好。

我在Postman中遇到同样的错误

任何想法??

1 个答案:

答案 0 :(得分:1)

  

reqstring + ="& resource =" + Uri.EscapeUriString(" https://keyvaultaccess.azurewebsites.net");

由于您将resource参数设置为https://keyvaultaccess.azurewebsites.net,我认为您已将AAD应用的应用ID ID (clientId等于5f315431-xxxxxxx-4e257b1b9295)设置为https://keyvaultaccess.azurewebsites.net。我假设您可以检索access_token,但是当使用access_token访问您的azure函数端点时,您获得了401状态代码。

您需要修改Active Directory身份验证的高级管理模式,将https://keyvaultaccess.azurewebsites.net添加到允许的令牌听众,或者在发送令牌时将resource参数更改为您的AAD clientID请求获取access_token。

Active Directory身份验证配置:

enter image description here

<强> TEST:

enter image description here

对JWT令牌进行Docode以检查aud属性:

enter image description here

访问我的Azure功能端点:

enter image description here

注意:您需要按照以下方式处理您的功能的授权级别:

enter image description here

如果您还启用了功能级别身份验证,则发送到azure功能的请求需要在查询字符串中包含相关的代码参数,或者使用功能键的值设置标题x-functions-key,或者您可以设置授权级别为Anonymous。