Я пытаюсь подключиться к онлайн-экземпляру Dynamics 365, используя стороннего поставщика удостоверений, PingFed.Я не несу ответственности за настройку этого провайдера идентификации и не имею доступа ни к одному из его параметров.
Используя приведенный ниже код, я могу определить провайдера аутентификации и успешно выполнить аутентификацию, однако, как только мыперенаправляется на службы входа в Microsoft, выдается ошибка, которую я перехватил через Fiddler.Если посмотреть на утверждение SAML, то это SAML 1.1.
Полученная нами ошибка:
The request is not a valid SAML 2.0 protocol message
Если я аутентифицируюсь с помощью интерактивного приглашения, я могу успешно войти в систему. Это не будет соответствовать нашим потребностямпоскольку нам необходимо иметь учетную запись службы для аутентификации в CRM.
Почему это работает, когда мы входим в систему в интерактивном режиме, а не когда мы пытаемся с помощью кода?
Команда, отвечающая за управление аутентификацией, не можетчтобы помочь, поэтому я надеялся, что кто-нибудь сможет пролить свет на то, что происходит?
public static void OverrideExample(bool usePrompt = false)
{
try
{
// Define organization Url
Uri orgUrl = new Uri("https://myorg.crm6.dynamics.com");
bool usePrompt = false;
// Call your existing authentication implementation
AuthenticationResult accessToken = MichelOverrideExampleHookImplementation.GetAccessTokenFromAzureAD(orgUrl, usePrompt);
// Create instance of your hook
var hook = new MichelOverrideExampleHookImplementation();
// Add token to your hook
hook.AddAccessToken(orgUrl, accessToken);
// Register the hook with the CrmServiceClient
CrmServiceClient.AuthOverrideHook = hook;
// Create a new instance of CrmServiceClient, pass your organization url and make sure useUniqueInstance = true!
var client = new CrmServiceClient(orgUrl, useUniqueInstance: true);
if (!client.IsReady)
{
// Connection failed, report error
Console.Error.WriteLine(client.LastCrmException?.Message ?? client.LastCrmError);
}
else
{
// Connection success
// TODO Add your code here
var qry = new QueryExpression("account");
qry.ColumnSet = new ColumnSet(true);
var results = client.RetrieveMultiple(qry);
Console.WriteLine("Connection Succesfull!");
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
}
}
public class MichelOverrideExampleHookImplementation : IOverrideAuthHookWrapper
{
// In memory cache of access tokens
Dictionary<string, AuthenticationResult> accessTokens = new Dictionary<string, Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult>();
public void AddAccessToken(Uri orgUri, Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult accessToken)
{
// Access tokens can be matched on the hostname,
// different endpoints in the same organization can use the same access token
accessTokens[orgUri.Host] = accessToken;
}
public string GetAuthToken(Uri connectedUri)
{
// Check if you have an access token for this host
if (accessTokens.ContainsKey(connectedUri.Host) && accessTokens[connectedUri.Host].ExpiresOn > DateTime.Now)
{
return accessTokens[connectedUri.Host].AccessToken;
}
else
{
accessTokens[connectedUri.Host] = GetAccessTokenFromAzureAD(connectedUri);
}
return null;
}
public static AuthenticationResult GetAccessTokenFromAzureAD(Uri orgUrl,bool usePrompt = false)
{
string resource = "https://myorg.crm6.dynamics.com";
AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(
new Uri("https://myorg.crm6.dynamics.com/api/data/")).Result;
String authorityUrl = ap.Authority;
String resourceUrl = ap.Resource;
// TODO Substitute your correct CRM root service address,
// 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 = "120e36b3-0d1a-4596-a0d4-b31eb384607e";
string redirectUrl = "app://myredirecturl";
var userCred = new UserCredential("user@myorg.com", "password");
// Authenticate the registered application with Azure Active Directory.
//Previous authority urls: https://login.windows.net/common
AuthenticationContext authContext = new AuthenticationContext(authorityUrl, false);
AuthenticationResult result = null;
if (usePrompt)
{
result = authContext.AcquireToken(resource, clientId, new Uri(redirectUrl));
}
else
{
result = authContext.AcquireToken(resourceUrl, clientId, userCred);
}
return result;
}