401-使用REST API Dynamics CRM和Azure AD进行未经授权的身份验证
我正在尝试使用Azure AD oAuth 2身份验证访问Dynamics CRM Online REST API。为此,我遵循以下步骤:401-使用REST API Dynamics CRM和Azure AD进行未经授权的身份验证,rest,azure,oauth-2.0,dynamics-crm,adal,Rest,Azure,Oauth 2.0,Dynamics Crm,Adal,我正在尝试使用Azure AD oAuth 2身份验证访问Dynamics CRM Online REST API。为此,我遵循以下步骤: -我已在Azure中注册了web应用程序和/或web api -将Dynamics CRM的权限配置为具有“以组织用户身份访问CRM Online”的委派权限 -并创建了一个过期1年的密钥,并保留生成的客户端ID。 在Azure上配置web应用程序后,我在.NET/C#中创建了一个控制台应用程序,该应用程序使用ADAL发出简单请求,在本例中检索帐户列表:
-我已在Azure中注册了web应用程序和/或web api
-将Dynamics CRM的权限配置为具有“以组织用户身份访问CRM Online”的委派权限
-并创建了一个过期1年的密钥,并保留生成的客户端ID。
在Azure上配置web应用程序后,我在.NET/C#中创建了一个控制台应用程序,该应用程序使用ADAL发出简单请求,在本例中检索帐户列表:
class Program
{
private static string ApiBaseUrl = "https://xxxxx.api.crm4.dynamics.com/";
private static string ApiUrl = "https://xxxxx.api.crm4.dynamics.com/api/data/v8.1/";
private static string ClientId = "2a5dcdaf-2036-4391-a3e5-9d0852ffe3f2";
private static string AppKey = "symCaAYpYqhiMK2Gh+E1LUlfxbMy5X1sJ0/ugzM+ur0=";
static void Main(string[] args)
{
AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(new Uri(ApiUrl)).Result;
var clientCredential = new ClientCredential(ClientId, AppKey);
var authenticationContext = new AuthenticationContext(ap.Authority);
var authenticationResult = authenticationContext.AcquireToken(ApiBaseUrl, clientCredential);
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
var result = httpClient.GetAsync(Path.Combine(ApiUrl, "accounts")).Result;
}
}
我成功地检索了访问令牌,但当我尝试对CRM执行httprequest时,我总是得到一个401-未经授权状态代码。我遗漏了什么?你的客户ID,Azure的AppKey,所以
ap.权限应该是https://login.microsoftonline.com/tenantid
invar authenticationContext=新的authenticationContext(ap.Authority)代码>我认为您至少无法绕开向某种“集成帐户”提供用户凭据。您可以通过以下方式避免更传统的弹出/重定向OAUTH流:
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.IO;
using System.Net;
namespace ConsoleApplication2
{
class Program
{
private static string API_BASE_URL = "https://<CRM DOMAIN>/";
private static string API_URL = "https://<CRM DOMAIN>/api/data/v8.1/";
private static string CLIENT_ID = "<CLIENT ID>";
static void Main(string[] args)
{
var userCredential = new UserCredential("<USERNAME>", "<PASSWORD>");
var authContext = new AuthenticationContext("https://login.windows.net/common", false);
var result = authContext.AcquireToken(API_BASE_URL, CLIENT_ID, userCredential);
var httpClient = HttpWebRequest.CreateHttp(Path.Combine(API_URL, "accounts"));
httpClient.Headers.Add(HttpRequestHeader.Authorization, "Bearer:" + result.AccessToken);
using (var sr = new StreamReader(httpClient.GetResponse().GetResponseStream()))
{
Console.WriteLine(sr.ReadToEnd());
}
Console.ReadLine();
}
}
}
使用Microsoft.IdentityModel.Clients.ActiveDirectory;
使用制度;
使用System.IO;
Net系统;
命名空间控制台应用程序2
{
班级计划
{
私有静态字符串API_BASE_URL=“https://”;
私有静态字符串API_URL=”https:///api/data/v8.1/";
私有静态字符串客户端_ID=“”;
静态void Main(字符串[]参数)
{
var userCredential=newusercredential(“,”);
var authContext=新的AuthenticationContext(“https://login.windows.net/common“,假);
var result=authContext.AcquireToken(API\u BASE\u URL、客户端\u ID、用户凭证);
var httpClient=HttpWebRequest.CreateHttp(Path.Combine(API_URL,“accounts”);
httpClient.Headers.Add(HttpRequestHeader.Authorization,“承载者:“+result.AccessToken”);
使用(var sr=newstreamreader(httpClient.GetResponse().GetResponseStream())
{
Console.WriteLine(sr.ReadToEnd());
}
Console.ReadLine();
}
}
}
注意:我使用的是旧版本的ADAL(),因为password
参数似乎已从UserCredential
构造函数中取出
编辑:CRM现在支持创建应用程序用户。我建议您查看服务器到服务器(S2S)身份验证,它在最新版本中添加到Dynamics 365中
通过使用S2S,您不需要付费的Dynamics 365许可证。应用程序的身份验证不是基于用户凭据,而是基于存储在Dynamics 365应用程序用户记录中的Azure AD对象ID值标识的服务主体
更多信息可在此处找到:
一年零两个月后,同样的代码可以完美地工作。正如许多人所说,Dynamics 365同时开始支持服务器到服务器(S2S)身份验证。我当时唯一没有做的一步就是创建一个应用程序用户。
有关如何使此身份验证生效的更多信息,请查看此网站:您可能需要在CRM中设置应用程序用户以与Azure应用程序相匹配:
虽然您可以在C#中设置承载令牌,但由于CRM级别的权限,对CRM资源的web请求可能会失败。谢谢大家的回答。我最终使用ADAL3访问了DynamicsCRM ODataAPI
由于许多人在执行此操作时仍有问题,请参阅以下步骤:
应用程序注册
使用Dynamics CRM订阅的Office 365管理员用户登录portal.azure.com
转到Azure Active Director\App registrations并添加新的应用程序注册
输入“名称”和“登录URL”,URL可以是任何内容(例如)
选择您刚刚创建的注册应用,转到设置\按键
输入密钥描述,单击“保存”并复制该值(并保留该值,因为以后需要它)。同时复制已注册应用程序的应用程序ID
转到“所需权限”,单击添加,选择“Dynamics CRM Online”,然后勾选“作为组织用户访问CRM Online”
这些步骤使客户机应用程序能够使用在步骤5中创建的应用程序ID和客户机机密访问Dynamics CRM。
您的客户端应用程序现在可以通过Azure AD进行身份验证,并具有访问CRM Online的权限。然而,CRM Online不知道这个“客户端应用程序”或“用户”。如果您尝试访问,CRM API将响应401
添加CRM应用程序用户
要让CRM了解“客户端应用程序”或“用户”,您需要添加一个应用程序用户
转到CRM\Security Roles,创建新的安全角色或仅复制“系统管理员”角色
转到CRM\Settings\Security\Users,创建新用户,将表单更改为“应用程序用户”
使用上一步中的应用程序ID输入必填字段。保存后,CRM将自动填充Azure AD对象ID和URI
将用户添加到从上一步创建的安全角色
现在,您应该能够使用以下示例代码,使用HttpClient和ADAL访问CRM API:
var ap=await AuthenticationParameters.CreateFromResourceUrlAsync(
新的Uri(“https://*****api.crm6.dynamics.com/api/data/v9.0/”);
字符串authorityUrl=ap.Authority;
字符串resourceUrl=ap.Resource;
var authContext=新的AuthenticationContext(authorityUrl);
var clientCred=new ClientCredential(“应用程序ID”)