利用 Microsoft Dynamics 365(联机)Web 服务对 Office 365 用户进行身份验证

 

发布日期: 2017年1月

适用于: Dynamics 365 (online),Dynamics 365 (on-premises),Dynamics CRM 2016,Dynamics CRM Online

该主题适用于通过 Microsoft Online Services 环境 访问 Microsoft Dynamics 365 (online) 的客户。 当您开发连接到组织或发现网站服务的一种应用时,有 Microsoft Dynamics 365 (online) 必须考虑的多位身分提供者。 这些提供商可被识别为托管域、联合和 Microsoft 帐户。 本主题集中讨论托管域和联合身分提供商的 Microsoft Dynamics 365 (online) Web 服务身份验证,虽然此处显示的同类和代码也可用于所有受支持的身分提供者和 Microsoft Dynamics 365 部署类型。

本主题内容

使用被简化的身份验证类

使用Office 365验证Microsoft用户

身份验证深潜

使用被简化的身份验证类

利用 Web 服务进行身份验证时,可以使用 OrganizationServiceProxyDiscoveryServiceProxy 类。 有关使用这些代理类别的详细信息,请参阅使用客户端代理类进行身份验证

另一种身份验证方法使用 CrmConnection 类。 利用一些代码行,您的应用程序便可利用 Web 服务通过身份验证,并开始调用 Web 方法。 有关 CrmConnection 类的详细信息,请参阅简化与 Microsoft Dynamics CRM 的连接。 示例代码位于示例:使用 Microsoft Dynamics CRM 简化连接快速入门主题中。

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

其他身份验证方法将使用 SDK 提供的帮助程序源代码。帮助程序代码:ServerConnection 类 主题中显示的 ServerConnection 帮助程序类提供 GetOrganizationProxyGetProxy 身份验证方法。 如果您查找的原始代码为 ServerConnection,则将看见 GetOrganizationProxy 实际上调用了 GetProxy

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

您必须在 using 声明中创建这些组织或发现服务代理对象,以便恰当地处理服务代理,或者请直接调用 Dispose。 对于使用 GetOrganizationProxy 帮助程序代码方法,请参阅 示例:Microsoft Dynamics 365 快速入门指南

可在 Microsoft Dynamics 365 SDK 中获取的认证类的完整列表如 身份验证类别 部分中所显示。

使用Office 365验证Microsoft用户

您的申请需要支持这些e Microsoft Dynamics 365 (online) 用户,这些用户的组织从 Microsoft 帐户身份提供者转变为Microsoft Online Services身份提供者。 在这种情况下,当用户利用 Microsoft Dynamics 365 (online) 的 Microsoft Online Services 身份提供程序进行身份验证时,用户可提供其 Microsoft 帐户 登录凭据。

为此,请将填充的凭据传入 OrganizationServiceProxy 构造函数或传入 IServiceManagement 类的 Authenticate 方法。 凭证值填充如下:

AuthenticationCredentials.ClientCredentials = <Microsoft account sign-in credentials>
AuthenticationCredentials.SupportingCredentials.ClientCredentials = <device credentials>

通过使用DeviceIdManager 辅助代码中的公共方法,例如LoadOrRegister,您可获取装置证书。 有关详细信息,请参阅帮助程序代码:DeviceIdManager 类

如果您的代码检查身份提供者类型,以决定如何验证,则随后要求提供附加代码。 参看下一节中的 GetCredentials方法,该方法用于支持所转换的Microsoft 帐户用户的示例代码。

有关此转换的详细信息,请参看将 Microsoft Dynamics 365(联机)与 Office 365 集成

身份验证深潜

此先期讨论介绍了可以利用 Microsoft Dynamics 365 Web 服务对用户进行身份验证的两种简单方法 。 以下信息显示如何通过使用 IServiceManagement<TService> 类对用户进行身份验证,并且将原始代码包括在 GetProxy 方法中。 要查看包含以下例子的完全示例,请参阅 示例:通过 Microsoft Dynamics 365 Web 服务对用户进行验证。 您将注意到,这个级别的身份认证采取大量代码。

以下示例代码展示了您的应用能使用证实使用网站服务的 Office 365 /MOS 用户的类 Microsoft Dynamics 365 (online) web 服务。


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 服务代理的引用。


/// <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 方法调用,然后服务代理实例化。 请注意,身份验证凭据从 Authenticate 返回,包含用于服务代理构建者的安全令牌响应。 以前显示的普通 GetProxy 方法可用于得到 OrganizationServiceProxyDiscoveryServiceProxy 的对象引用。

另请参阅

连接 Microsoft Office 365 和 Microsoft Dynamics 365(联机)
Microsoft Dynamics 365(联机)和 Office 365 中的同步用户
示例:通过 Microsoft Dynamics 365 Web 服务对用户进行验证
帮助程序代码:ServerConnection 类
活动目录和基于声明的身份验证
使用 XRM 工具中的连接字符串连接至 Dynamics 365

Microsoft Dynamics 365

© 2017 Microsoft。 保留所有权利。 版权