如何将服务器服务连接到Dynamics Online

时间:2016-03-22 17:04:12

标签: c# dynamics-crm dynamics-crm-2016

我正在修改内部管理应用程序以连接到我们在线托管的Dynamics 2016实例。

在一些在线教程之后,我一直在使用SDK中OrganizationServiceProxy的{​​{1}}。

这似乎需要一个用户名和密码来连接,这很好,但我想以某种方式连接,不需要特定用户的帐户详细信息。我不认为我见过的OAuth示例是合适的,因为没有用户界面,也没有真人来显示OAuth请求。

Microsoft.Xrm.Sdk.Client

有没有办法连接应用程序令牌或API密钥?

3 个答案:

答案 0 :(得分:0)

使用Microsoft Dynamics CRM Online或面向Internet的部署 当您使用Web API 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));

PS:关于您的方法,最佳做法是将密码存储为明文,加密或加密配置部分最大的安全性。

See walkhrough here

希望这会有所帮助:)

答案 1 :(得分:0)

如果我正确理解了您的问题,则希望通过具有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 = "jennie.whiten@mycompany.com";
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保护凭据的安全。

答案 2 :(得分:0)

我发现要成功完成此操作,您需要设置以下所有内容:

  1. 在Azure AD中创建应用程序注册:
    • 向其授予Dynamics的API权限,特别是“以组织用户身份访问Dynamics 365”
    • 给它一个虚拟的Web重定向URI,例如http://localhost/auth
    • 生成客户端机密并将其保存以供以后使用
  2. 在Azure AD中创建一个用户帐户,并将其授予Dynamics权限。
  3. 使用与上述非交互式用户帐户相同的电子邮件在Dynamics中创建应用程序用户记录。
  4. 使用您创建的用户帐户对应用程序进行身份验证。

对于第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());
    }
}