簡體   English   中英

Azure到Dynamics CRM 2011:如何實施AD身份驗證?

[英]Azure to Dynamics CRM 2011: how to implement AD authentication?

為了在CRM安裝中更好地顯示數據,我們有一個Azure網站,該網站基本上會讀取我們要處理的CRM數據(員工的工作計划時間),並使用Telerik(計划程序)將其轉換為更易於閱讀的格式使用定期約會)。 Telerik約會從不轉換回,因此它是與CRM的只讀連接。

我們已經使用固定用戶進行身份驗證,該產品運行良好,但是當我們要使用當前登錄的用戶進行身份驗證時,遇到了涉及AD的問題。 下面代碼中的currentUserId是通過表單中的querystring傳遞的。

private OrganizationServiceProxy CreateOrganizationService(String serverAddress, String organizationName, Guid currentUserId)
{
    var discoveryServiceUri = serverAddress.Contains("http") ? new Uri(String.Format("{0}/XRMServices/2011/Discovery.svc", serverAddress)) : new Uri(String.Format("http://{0}/XRMServices/2011/Discovery.svc", serverAddress));
    System.Diagnostics.Trace.TraceInformation("current discoveryUri: " + discoveryServiceUri);
    var credentials = new ClientCredentials();
    // Get the user's logon credentials.
    credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
    System.Diagnostics.Trace.TraceInformation("current user: " + CredentialCache.DefaultNetworkCredentials.UserName);
    // Get the target organization.
    var organizationUri = GetOrganizationAddress(organizationName, discoveryServiceUri, credentials, null);
    System.Diagnostics.Trace.TraceInformation("current organization: " + organizationUri);
    var serviceProxy = new OrganizationServiceProxy(organizationUri, null, credentials, null);
    // This statement is required to enable early-bound type support.
    serviceProxy.EnableProxyTypes();
    if (currentUserId == Guid.Empty)
    {
       currentUserId = GetUserId(serviceProxy);
    }
    if (currentUserId != Guid.Empty)
       serviceProxy.CallerId = currentUserId;
    return serviceProxy;
}

上面的代碼用於在服務器端創建CRM連接。

private Uri GetOrganizationAddress(String organizationName, Uri discoveryServiceUri, ClientCredentials credentials, ClientCredentials deviceCredentials)
    {
        if (discoveryServiceUri == null)
            throw new Exception("DiscoveryServiceUri is null. Please specify a valid configuration details to connect crm server.");
        using (var serviceProxy = new DiscoveryServiceProxy(discoveryServiceUri, null, credentials, deviceCredentials))
        {
            // Obtain organization information from the Discovery service.
            {
                // Obtain information about the organizations that the system user belongs to.
                System.Diagnostics.Trace.TraceInformation("getting organizationss now");
                OrganizationDetailCollection orgs = DiscoverOrganizations(serviceProxy);
                System.Diagnostics.Trace.TraceInformation(orgs.Count + " organizations discovered");
                if (orgs.Count > 0)
                {
                    int orgNumber = 0;
                    for (int n = 0; n < orgs.Count; n++)
                    {
                        if (orgs[n].UniqueName == organizationName || orgs[n].FriendlyName == organizationName)
                        {
                            orgNumber = n + 1;
                            System.Diagnostics.Trace.TraceInformation("orgs[n].UniqueName: " + orgs[n].UniqueName);
                            System.Diagnostics.Trace.TraceInformation("orgs[n].friendlyName: " + orgs[n].FriendlyName);
                            break;
                        }
                    }
                    if (orgNumber > 0 && orgNumber <= orgs.Count)
                    {
                        Version version = new Version(orgs[orgNumber - 1].OrganizationVersion);
                        System.Diagnostics.Trace.TraceInformation("version: " + version.Build);
                        // Return the organization Uri.
                        Uri uri =  new Uri(orgs[orgNumber - 1].Endpoints[EndpointType.OrganizationService]);
                        System.Diagnostics.Trace.TraceInformation("uri:" + uri);
                        return uri;
                    }
                    throw new Exception(string.Format("The specified organization '{0}' does not exist.", organizationName));
                }
                throw new Exception(string.Format("You do not belong to any organizations on the specified server. DiscoveryServiceUri '{0}'", discoveryServiceUri.AbsoluteUri));
            }
        }
    }

下面的代碼出了問題:

private OrganizationDetailCollection DiscoverOrganizations(IDiscoveryService service)
    {
        var orgRequest = new RetrieveOrganizationsRequest();
        System.Diagnostics.Trace.TraceInformation("orgrequest made");
        var orgResponse = (RetrieveOrganizationsResponse)service.Execute(orgRequest);
        System.Diagnostics.Trace.TraceInformation("orgresponse retrieved: " + orgResponse);

        System.Diagnostics.Trace.TraceInformation("orgResponse.details: " + orgResponse.Details);
        return orgResponse.Details;
    }

在Execute(orgRequest)命令上出錯。 我已將此問題歸結為AD身份驗證的問題,即我的憑據似乎是錯誤的。 我想將當前正在使用CRM的AD用戶帳戶(而非CRM用戶帳戶)使用的AD憑據傳遞給第一種方法中的憑據對象。

目的是僅在Dynamics CRM 2011內部使用此應用程序,但從理論上講,它也應在平台之外工作以進行測試。

編輯:剛剛意識到我忘記了我的堆棧跟蹤:

System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.
   at System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
   at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)The caller was not authenticated by the service.
Server stack trace: 
   at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
   at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout)
   at System.ServiceModel.Security.SecurityProtocol.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

我的一位同事幫助了我。 事實證明,Azure只能讀取AD的DefaultNetworkCredentials。 但是,Dynamics CRM 2011不接受這些憑據進行身份驗證。 我們正在尋找替代解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM