3

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

按照一些在线教程,我一直在使用SDKOrganizationServiceProxy中的一个。Microsoft.Xrm.Sdk.Client

这似乎需要用户名和密码才能连接,效果很好,但我想以某种不需要特定用户帐户详细信息的方式进行连接。我不认为我见过的 OAuth 示例是合适的,因为没有 UI,也没有实际的人来显示 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 密钥?

4

3 回答 3

1

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

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

对于第 4 步,您需要打开一个新的隐身窗口,使用以下模式构建一个 url,并在第 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());
    }
}
于 2019-02-19T21:57:30.803 回答
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:关于您的方法,最好不要将密码存储为明文、加密或加密配置部分以获得最大的安全性。

在此处查看演练

希望这可以帮助 :)

于 2016-03-23T09:24:39.453 回答
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));

您还可以查看以下链接验证 Azure Function App 以连接到 Dynamics 365 CRM Online,该链接描述了如何使用 Azure Key Vault 保护您的凭据。

于 2018-12-12T21:31:31.970 回答