我正在修改内部管理应用程序以连接到我们的在线托管Dynamics 2016实例。
在一些在线教程之后,我一直在使用SDK中的OrganizationServiceProxy
中的Microsoft.Xrm.Sdk.Client
。
这似乎需要一个用户名和密码来连接,这很好,但我想以某种方式连接,不需要特定用户的帐户详细信息。我不认为我见过的OAuth示例是合适的,因为没有用户界面,也没有真人来显示OAuth请求。
public class DynamicsHelper
{
private OrganizationServiceProxy service;
public void Connect(string serviceUri, string username, string password)
{
var credentials = new ClientCredentials();
credentials.UserName.UserName = username;
credentials.UserName.Password = password;
var organizationUri = new Uri(serviceUri);
this.service = new OrganizationServiceProxy(organizationUri, null, credentials, null);
}
}
有没有办法连接应用程序令牌或API密钥?
使用Microsoft Dynamics CRM Online或面向Internet的部署使用Web Online for CRM Online或本地面向Internet的部署(IFD)时,必须使用OAuth,如使用OAuth连接到Microsoft Dynamics CRM Web服务中所述。
在使用OAuth身份验证连接CRM Web服务之前,必须首先在Microsoft Azure Active Directory中注册您的应用程序。 Azure Active Directory用于验证是否允许您的应用程序访问存储在CRM租户中的业务数据。
// TODO Substitute your correct CRM root service address,
string resource = "https://mydomain.crm.dynamics.com";
// TODO Substitute your app registration values that can be obtained after you
// register the app in Active Directory on the Microsoft Azure portal.
string clientId = "e5cf0024-a66a-4f16-85ce-99ba97a24bb2";
string redirectUrl = "http://localhost/SdkSample";
// Authenticate the registered application with Azure Active Directory.
AuthenticationContext authContext =
new AuthenticationContext("https://login.windows.net/common", false);
AuthenticationResult result =
authContext.AcquireToken(resource, clientId, new Uri(redirectUrl));
P.S:关于您的方法,最佳做法是不将密码存储为明文,加密或加密配置部分以获得最大安全性。
希望这可以帮助 :)
如果我正确理解您的问题,您希望通过带有ClientId和Secret的注册Azure应用程序而不是用户名和密码连接到Dynamics 2016(Dynamics 365)。如果这是正确的,那么可以使用OrganizationWebProxyClient 。您甚至可以使用强类型程序集。
var organizationWebProxyClient = new OrganizationWebProxyClient(GetServiceUrl(), true);
organizationWebProxyClient.HeaderToken = authToken.AccessToken;
OrganizationRequest request = new OrganizationRequest()
{
RequestName = "WhoAmI"
};
WhoAmIResponse response = organizationWebProxyClient.Execute(new WhoAmIRequest()) as WhoAmIResponse;
Console.WriteLine(response.UserId);
Contact contact = new Contact();
contact.EMailAddress1 = "[email protected]";
contact.FirstName = "Jennie";
contact.LastName = "White";
contact.Id = Guid.NewGuid();
organizationWebProxyClient.Create(contact);
要获取AccessToken,请参阅以下帖子Connect to Dynamics CRM WebApi from Console Application。
替换第66行(完整源代码)
authToken = await authContext.AcquireTokenAsync(resourceUrl, clientId, new Uri(redirectUrl), new PlatformParameters(PromptBehavior.Never));
同
authToken = await authContext.AcquireTokenAsync( resourceUrl, new ClientCredential(clientId, secret));
您还可以查看以下链接Authenticate Azure Function App to connect to Dynamics 365 CRM online,其中介绍了如何使用Azure Key Vault保护凭据。
我发现要成功完成此操作,您需要设置以下所有内容:
http://localhost/auth
生成客户端密钥并保存以供日后使用对于第4步,您需要打开一个新的隐身窗口,使用以下模式构建网址并使用您在步骤2中的用户帐户凭据登录:
https://login.microsoftonline.com/<your aad tenant id>/oauth2/authorize?client_id=<client id>&response_type=code&redirect_uri=<redirect uri from step 1>&response_mode=query&resource=https://<organization name>.<region>.dynamics.com&state=<random value>
完成此操作后,您应该看到您的Dynamics应用程序用户具有应用程序ID和应用程序ID URI。
现在使用ClientId和ClientSecret以及一些其他组织特定变量,您可以使用Azure Active Directory(AAD)进行身份验证以获取oauth令牌并构建OrganizationWebProxyClient
。我从来没有找到完成此代码的完整代码示例,但我已经为自己的目的开发了以下内容。请注意,您获得的令牌的有效期为1小时。
internal class ExampleClientProvider
{
// Relevant nuget packages:
// <package id="Microsoft.CrmSdk.CoreAssemblies" version="9.0.2.9" targetFramework="net472" />
// <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="4.5.1" targetFramework="net461" />
// Relevant imports:
// using Microsoft.IdentityModel.Clients.ActiveDirectory;
// using Microsoft.Crm.Sdk.Messages;
// using Microsoft.Xrm.Sdk;
// using Microsoft.Xrm.Sdk.Client;
// using Microsoft.Xrm.Sdk.WebServiceClient;
private const string TenantId = "<your aad tenant id>"; // from your app registration overview "Directory (tenant) ID"
private const string ClientId = "<your client id>"; // from your app registration overview "Application (client) ID"
private const string ClientSecret = "<your client secret>"; // secret generated in step 1
private const string LoginUrl = "https://login.microsoftonline.com"; // aad login url
private const string OrganizationName = "<your organization name>"; // check your dynamics login url, e.g. https://<organization>.<region>.dynamics.com
private const string OrganizationRegion = "<your organization region>"; // might be crm for north america, check your dynamics login url
private string GetServiceUrl()
{
return $"{GetResourceUrl()}/XRMServices/2011/Organization.svc/web";
}
private string GetResourceUrl()
{
return $"https://{OrganizationName}.api.{OrganizationRegion}.dynamics.com";
}
private string GetAuthorityUrl()
{
return $"{LoginUrl}/{TenantId}";
}
public async Task<OrganizationWebProxyClient> CreateClient()
{
var context = new AuthenticationContext(GetAuthorityUrl(), false);
var token = await context.AcquireTokenAsync(GetResourceUrl(), new ClientCredential(ClientId, ClientSecret));
return new OrganizationWebProxyClient(new Uri(GetServiceUrl()), true)
{
HeaderToken = token.AccessToken,
SdkClientVersion = "9.1"
};
}
public async Task<OrganizationServiceContext> CreateContext()
{
var client = await CreateClient();
return new OrganizationServiceContext(client);
}
public async Task TestApiCall()
{
var context = await CreateContext();
// send a test request to verify authentication is working
var response = (WhoAmIResponse) context.Execute(new WhoAmIRequest());
}
}