Проблемы с аутентификацией в Dynamics 365 с помощью PingFed - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь подключиться к онлайн-экземпляру 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;
    }

1 Ответ

0 голосов
/ 13 сентября 2018

При определении соединения в PingFed (определяется из приведенного выше кода как clientId = "120e36b3-0d1a-4596-a0d4-b31eb384607e"), вы настраиваете тип соединения - Профили SSO браузера, WS-Trust - вам необходимо указать протокол как SAML 2.0.

...