分享方式:


向 Microsoft Dynamics CRM Online Web 服務驗證 Office 365 使用者

 

發佈日期: 2016年11月

適用對象: Dynamics CRM 2015

本主題適用於透過 Microsoft Online Services 環境存取 Microsoft Dynamics CRM Online 的客戶。 開發連線至組織或 Discovery Web 服務的應用程式時,必須考慮到多個 Microsoft Dynamics CRM Online 身分識別提供者。 這些提供者可識別為受管理網域、同盟與 Microsoft 帳號。 本主題著重於具有受管理網域與同盟身分識別提供者的 Microsoft Dynamics CRM Online Web 服務驗證,雖然這裡顯示的相同類別及程式碼也適用於任何支援的身分識別提供者以及 Microsoft Dynamics 365 部署類型。

本主題內容

使用簡化驗證類型

使用 Office 365 驗證 Microsoft 帳戶使用者

深入了解驗證

使用簡化驗證類型

使用 Web 服務驗證時,可以使用 OrganizationServiceProxyDiscoveryServiceProxy 類別。 如需關於使用這些 Proxy 類別的詳細資訊,請參閱 使用用戶端 proxy 類別的驗證

另一個驗證方法使用 CrmConnection 類別。 只要數行程式碼,您的應用程式可以使用 Web 服務驗證並開始呼叫 Web 方法。 如需 CrmConnection 類別的詳細資訊,請參閱 簡化的 Microsoft Dynamics CRM 2015 連線。 範例程式碼可在範例:使用 Microsoft Dynamics CRM 的簡化連線快速入門主題中找到。

CrmConnection connection = CrmConnection.Parse (connectionString);
using ( OrganizationService orgService = new OrganizationService(connection)) { }

另一個驗證方法是使用 SDK 提供的 Helper 來源程式碼。ServerConnection Helper 類別 (Helper 程式碼:ServerConnection 類別 主題中顯示) 提供驗證 GetOrganizationProxyGetProxy 方法。 如果檢視 ServerConnection 來源程式碼,您會看到 GetOrganizationProxy 實際呼叫 GetProxy

using ( OrganizationServiceProxy orgServiceProxy = ServerConnection.GetOrganizationProxy(serverConfig) ) { }

您必須在 using 陳述式建立這些組織或探索服務 Proxy 物件才能正確處置服務 Proxy,或是直接呼叫 Dispose。 如需使用 GetOrganizationProxy Helper 程式碼方法的範例程式碼,請參閱 範例:Microsoft Dynamics CRM 快速入門

Microsoft Dynamics CRM SDK 中可用驗證類型的完整清單在驗證類別一節中顯示。

使用 Office 365 驗證 Microsoft 帳戶使用者

您的應用程式必須支援 Microsoft Dynamics CRM Online 使用者,其組織從 Microsoft 帳號 身分識別提供者轉換至 Microsoft Online Services 身分識別提供者。 在這種情況下,當使用者與 Microsoft Dynamics CRM Online 的 Microsoft Online Services 身分識別提供者驗證時,使用者可提供 Microsoft 帳號 登入認證。

若要這麼做,請在 OrganizationServiceProxy 建構函式或 IServiceManagement 類別的 Authenticate 方法中傳遞填入的登入認證。 填入的認證值如下:

AuthenticationCredentials.ClientCredentials = <Microsoft account logon credentials>
AuthenticationCredentials.SupportingCredentials.ClientCredentials = <device credentials>

使用其中一個公用方法,例如在 DeviceIdManager Helper 程式碼中的 LoadOrRegister,即可取得裝置認證。 如需詳細資訊,請參閱Helper 碼:DeviceIdManager 類別

如果您的程式碼檢查身分識別提供者類型決定如何驗證,則需要其他程式碼。 如需支援轉換 Microsoft 帳號 使用者的範例程式碼,請參閱下一節的 GetCredentials 方法。

如需此轉換的詳細資訊,請參閱 Microsoft Dynamics CRM Online 與 Office 365 整合

深入了解驗證

先前討論介紹兩個用來在 Microsoft Dynamics 365 Web 服務驗證使用者的簡單方式。 下列資訊顯示如何使用 IServiceManagement<TService> 類別驗證使用者,並包含來源程式碼至 GetProxy 方法。 若要查看包含下列範例的完整範例,請參閱 範例:向 Microsoft Dynamics CRM Web 服務驗證使用者。 您會注意到,這個等級的驗證使用大量程式碼。

下列範例程式碼示範可用於您的應用程式中,使用 Microsoft Dynamics CRM Online Web 服務來驗證 Office 365/MOS 使用者的類別和方法。


IServiceManagement<IOrganizationService> orgServiceManagement =
    ServiceConfigurationFactory.CreateManagement<IOrganizationService>(
    new Uri(organizationUri));

// Set the credentials.
AuthenticationCredentials credentials = GetCredentials(orgServiceManagement, endpointType);

// Get the organization service proxy.
using (OrganizationServiceProxy organizationProxy =
    GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
{
    // This statement is required to enable early-bound type support.
    organizationProxy.EnableProxyTypes();

    // Now make an SDK call with the organization service proxy.
    // Display information about the logged on user.
    Guid userid = ((WhoAmIResponse)organizationProxy.Execute(
        new WhoAmIRequest())).UserId;
    SystemUser systemUser = organizationProxy.Retrieve("systemuser", userid,
        new ColumnSet(new string[] { "firstname", "lastname" })).ToEntity<SystemUser>();
    Console.WriteLine("Logged on user is {0} {1}.",
        systemUser.FirstName, systemUser.LastName);
}

Dim orgServiceManagement As IServiceManagement(Of IOrganizationService) =
    ServiceConfigurationFactory.CreateManagement(Of IOrganizationService)(New Uri(organizationUri))

' Set the credentials.
Dim credentials As AuthenticationCredentials = GetCredentials(endpointType_renamed)

' Get the organization service proxy.
Using organizationProxy As OrganizationServiceProxy =
    GetProxy(Of IOrganizationService, OrganizationServiceProxy)(orgServiceManagement, credentials)
    ' This statement is required to enable early-bound type support.
    organizationProxy.EnableProxyTypes()

    ' Now make an SDK call with the organization service proxy.
    ' Display information about the logged on user.
    Dim userid As Guid = (CType(organizationProxy.Execute(New WhoAmIRequest()), 
                          WhoAmIResponse)).UserId
    Dim systemUser_renamed As SystemUser =
        organizationProxy.Retrieve("systemuser",
                                   userid,
                                   New ColumnSet(New String() {"firstname",
                                                               "lastname"})).ToEntity(Of SystemUser)()
    Console.WriteLine("Logged on user is {0} {1}.",
                      systemUser_renamed.FirstName, systemUser_renamed.LastName)
End Using

程式碼建立組織服務的 IServiceManagement<TService> 物件。 類型 AuthenticationCredentials 物件用來包含使用者的登入認證。IServiceManagement 物件和使用者認證然後傳遞至 GetProxy,取得 Web 服務 Proxy 參照。


/// <summary>
/// Obtain the AuthenticationCredentials based on AuthenticationProviderType.
/// </summary>
/// <param name="service">A service management object.</param>
/// <param name="endpointType">An AuthenticationProviderType of the CRM environment.</param>
/// <returns>Get filled credentials.</returns>
private AuthenticationCredentials GetCredentials<TService>(IServiceManagement<TService> service, AuthenticationProviderType endpointType)
{
    AuthenticationCredentials authCredentials = new AuthenticationCredentials();

    switch (endpointType)
    {
        case AuthenticationProviderType.ActiveDirectory:
            authCredentials.ClientCredentials.Windows.ClientCredential =
                new System.Net.NetworkCredential(_userName,
                    _password,
                    _domain);
            break;
        case AuthenticationProviderType.LiveId:
            authCredentials.ClientCredentials.UserName.UserName = _userName;
            authCredentials.ClientCredentials.UserName.Password = _password;
            authCredentials.SupportingCredentials = new AuthenticationCredentials();
            authCredentials.SupportingCredentials.ClientCredentials =
                Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice();
            break;
        default: // For Federated and OnlineFederated environments.                    
            authCredentials.ClientCredentials.UserName.UserName = _userName;
            authCredentials.ClientCredentials.UserName.Password = _password;
            // For OnlineFederated single-sign on, you could just use current UserPrincipalName instead of passing user name and password.
            // authCredentials.UserPrincipalName = UserPrincipal.Current.UserPrincipalName;  // Windows Kerberos

            // The service is configured for User Id authentication, but the user might provide Microsoft
            // account credentials. If so, the supporting credentials must contain the device credentials.
            if (endpointType == AuthenticationProviderType.OnlineFederation)
            {
                IdentityProvider provider = service.GetIdentityProvider(authCredentials.ClientCredentials.UserName.UserName);
                if (provider != null &amp;&amp; provider.IdentityProviderType == IdentityProviderType.LiveId)
                {
                    authCredentials.SupportingCredentials = new AuthenticationCredentials();
                    authCredentials.SupportingCredentials.ClientCredentials =
                        Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice();
                }
            }

            break;
    }

    return authCredentials;
}

''' <summary>
''' Obtain the AuthenticationCredentials based on AuthenticationProviderType.
''' </summary>
''' <param name="endpointType">An AuthenticationProviderType of the CRM environment.</param>
''' <returns>Get filled credentials.</returns>
Private Function GetCredentials(ByVal endpointType As AuthenticationProviderType) As AuthenticationCredentials

    Dim authCredentials As New AuthenticationCredentials()
    Select Case endpointType
        Case AuthenticationProviderType.ActiveDirectory
                  authCredentials.ClientCredentials.Windows.ClientCredential =
                      New System.Net.NetworkCredential(_userName, _password, _domain)
        Case AuthenticationProviderType.LiveId
            authCredentials.ClientCredentials.UserName.UserName = _userName
            authCredentials.ClientCredentials.UserName.Password = _password
            authCredentials.SupportingCredentials = New AuthenticationCredentials()
                  authCredentials.SupportingCredentials.ClientCredentials =
                      Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice()
        Case Else ' For Federated and OnlineFederated environments.
            authCredentials.ClientCredentials.UserName.UserName = _userName
            authCredentials.ClientCredentials.UserName.Password = _password
            ' For OnlineFederated single-sign on, you could just use current UserPrincipalName instead of passing user name and password.
            ' authCredentials.UserPrincipalName = UserPrincipal.Current.UserPrincipalName;  //Windows/Kerberos
    End Select

    Return authCredentials
End Function

AuthenticationCredentials 物件是根據登入使用者的訂閱身分識別進行設定。 請注意,這裡顯示所有身分識別提供者類型的使用者認證。 預設案例處理以 Microsoft Office 365/MOS 受管理網域、其身分識別為雲端同盟的線上使用者,以及轉換的 Microsoft 帳號 使用者。 現在查看 GetProxy 實際執行哪些操作。


private TProxy GetProxy<TService, TProxy>(
    IServiceManagement<TService> serviceManagement,
    AuthenticationCredentials authCredentials)
    where TService : class
    where TProxy : ServiceProxy<TService>
{
    Type classType = typeof(TProxy);

    if (serviceManagement.AuthenticationType !=
        AuthenticationProviderType.ActiveDirectory)
    {
        AuthenticationCredentials tokenCredentials =
            serviceManagement.Authenticate(authCredentials);
        // Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments. 
        // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse.
        return (TProxy)classType
            .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) })
            .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse });
    }

    // Obtain discovery/organization service proxy for ActiveDirectory environment.
    // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials.
    return (TProxy)classType
        .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(ClientCredentials) })
        .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials });
}

Private Function GetProxy(Of TService As Class,
                              TProxy As ServiceProxy(Of TService)) _
                          (ByVal serviceManagement As IServiceManagement(Of TService),
                           ByVal authCredentials As AuthenticationCredentials) As TProxy
    Dim classType As Type = GetType(TProxy)

    If serviceManagement.AuthenticationType <>
        AuthenticationProviderType.ActiveDirectory Then
        Dim tokenCredentials As AuthenticationCredentials =
            serviceManagement.Authenticate(authCredentials)
        ' Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments. 
        ' Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse.
        Return CType(classType _
        .GetConstructor(New Type() {GetType(IServiceManagement(Of TService)), GetType(SecurityTokenResponse)}) _
        .Invoke(New Object() {serviceManagement, tokenCredentials.SecurityTokenResponse}), TProxy)
    End If

    ' Obtain discovery/organization service proxy for ActiveDirectory environment.
    ' Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials.
    Return CType(classType _
        .GetConstructor(New Type() {GetType(IServiceManagement(Of TService)), GetType(ClientCredentials)}) _
        .Invoke(New Object() {serviceManagement, authCredentials.ClientCredentials}), TProxy)
End Function

針對內部部署以外的所有部署 (Active Directory,沒有宣告),會叫用 Authenticate 方法,然後具現化服務 Proxy。 請注意,從 Authenticate 傳回的驗證認證包含用於服務 Proxy 建構函式的安全性權杖回應。 先前顯示的一般 GetProxy 方法可用來取得對 OrganizationServiceProxyDiscoveryServiceProxy 的物件參照。

另請參閱

與 Microsoft Office 365 及 Microsoft Dynamics CRM Online 連線
Microsoft Dynamics CRM Online 和 Office 365 已同步處理的使用者
範例:向 Microsoft Dynamics CRM Web 服務驗證使用者
Helper 程式碼:ServerConnection 類別
Active Directory 和宣告型驗證
簡化的 Microsoft Dynamics CRM 2015 連線

© 2017 Microsoft. 著作權所有,並保留一切權利。 著作權