Как подключить серверную службу к Dynamics Online
Я изменяю внутреннее приложение управления для подключения к нашему онлайн-экземпляру Dynamics 2016.
После некоторых онлайн-уроков, я использовал OrganizationServiceProxy
снаружи Microsoft.Xrm.Sdk.Client
из SDK.
Похоже, что для подключения требуются имя пользователя и пароль, что прекрасно работает, но я бы хотел подключиться таким образом, чтобы не требовались данные учетной записи конкретного пользователя. Я не думаю, что примеры 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?
1 ответ
Я обнаружил, что, чтобы сделать это успешно, вам нужно настроить все следующее:
- Создайте регистрацию приложения в Azure AD:
- предоставить ему разрешения API для Dynamics, в частности "Access Dynamics 365 как пользователи организации"
- дать ему фиктивный веб-редирект URI, такой как
http://localhost/auth
- создать секрет клиента и сохранить его на потом
- Создайте учетную запись пользователя в Azure AD и предоставьте ей разрешения для Dynamics.
- Создайте запись пользователя приложения в Dynamics с тем же адресом электронной почты, что и у неинтерактивной учетной записи выше.
- Аутентифицируйте ваше приложение, используя созданную вами учетную запись.
На шаге 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 есть идентификатор приложения и идентификатор 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());
}
}
Если я правильно понимаю ваш вопрос, вы хотите подключиться к Dynamics 2016 (Dynamics 365) через Зарегистрированное приложение Azure с ClientId и Secret вместо имени пользователя и пароля. Если это правильно, да, это возможно с 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, обратитесь к следующему сообщению Подключение к Dynamics CRM WebApi из консольного приложения.
Заменить строку 66 (полный исходный код)
authToken = await authContext.AcquireTokenAsync(resourceUrl, clientId, new Uri(redirectUrl), new PlatformParameters(PromptBehavior.Never));
с
authToken = await authContext.AcquireTokenAsync( resourceUrl, new ClientCredential(clientId, secret));
Можно также проверить следующее приложение Link Authenticate Azure Function App для подключения к Dynamics 365 CRM в Интернете, в котором описано, как защитить свои учетные данные с помощью хранилища ключей Azure.
С помощью Microsoft Dynamics CRM Online или развертываний в Интернете. При использовании веб-API для CRM Online или локального развертывания в Интернете (IFD) необходимо использовать OAuth, как описано в разделе Подключение к веб-службам Microsoft Dynamics CRM с помощью OAuth.
Прежде чем вы сможете использовать проверку подлинности OAuth для подключения к веб-службам CRM, ваше приложение должно быть сначала зарегистрировано в 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: Что касается вашего метода, то лучше не хранить пароль в виде открытого текста, не шифровать его и не шифровать разделы конфигурации для максимальной безопасности.
Надеюсь это поможет:)