【问题标题】:Problems Authenticating to Dynamics 365 using PingFed使用 PingFed 对 Dynamics 365 进行身份验证时出现问题
【发布时间】:2018-09-13 08:59:55
【问题描述】:

我正在尝试使用第三方身份提供商 PingFed 连接到 Dynamics 365 在线实例。我不负责此身份提供者的配置,也无权访问其任何设置。

使用下面的代码,我能够识别身份验证提供程序并成功进行身份验证,但是,一旦我们被重定向到 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;
    }

【问题讨论】:

    标签: dynamics-365 pingfederate


    【解决方案1】:

    在 PingFed 中定义连接时(从上面的代码定义为 clientId = "120e36b3-0d1a-4596-a0d4-b31eb384607e"),您配置连接类型 - 浏览器 SSO 配置文件,WS-Trust - 您需要指定协议为 SAML 2.0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-20
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 2013-08-23
      • 2019-02-21
      相关资源
      最近更新 更多