Authenticate Office 365 users with Customer Engagement web services
This topic applies to customers who access Dynamics 365 Customer Engagement (on-premises) through the Microsoft Online Services environment. There are multiple Dynamics 365 Customer Engagement (on-premises) identity providers that must be accounted for when you develop an application that connects to the Organization or Discovery web services. These providers can be identified as managed domain, federated, and Microsoft account. This topic focuses on Dynamics 365 Customer Engagement (on-premises) web service authentication with managed domain and federated identity providers, although the same classes and code shown here also work with all supported identity providers and Dynamics 365 Customer Engagement (on-premises) deployment types.
Use the simplified authentication classes
You can use the OrganizationServiceProxy and DiscoveryServiceProxy classes when authenticating with the web services.
For more information about using these proxy classes see Authentication by using the client proxy classes.
Note
The sample helper code containing the ServerConnection
class is no longer maintained and will be removed some time in the future. Instead, use one of the supported authentication APIs in the SDK assemblies such as CrmServiceClient.
Another authentication approach is to use the helper source code provided in the SDK. The ServerConnection
helper class, shown in
Helper Code: ServerConnection Class, provides GetOrganizationProxy
and GetProxy
methods for authentication.
If you look at the source code for ServerConnection
, you will see that GetOrganizationProxy
actually calls GetProxy
.
using ( OrganizationServiceProxy orgServiceProxy = ServerConnection.GetOrganizationProxy(serverConfig) ) { }
You must create these organization or discovery service proxy objects in a using
statement to correctly dispose of the service proxy,
or call Dispose
directly. For sample code that uses the GetOrganizationProxy
helper code method, see Sample: Quick Start.
The complete list of authentication classes available in the SDK assemblies are shown in the Authentication Classes section.
Authenticate Microsoft account users with Office 365
Your application needs to support those Dynamics 365 Customer Engagement (on-premises) users whose organization is transitioned from the Microsoft account identity provider to the Microsoft Online Services identity provider. In this scenario, users may provide their Microsoft account sign-in credentials when they authenticate with the Microsoft Online Services identity provider of Dynamics 365 Customer Engagement (on-premises).
To do this, pass the populated credentials in the OrganizationServiceProxy constructor or the AuthenticationCredentials method of the IServiceManagement
class. The credential values are populated as follows:
AuthenticationCredentials.ClientCredentials = <Microsoft account sign-in credentials>
AuthenticationCredentials.SupportingCredentials.ClientCredentials = <device credentials>
If your code checks the identity provider type to determine how to authenticate, then additional code is required. See the GetCredentials
method in the next section for sample code that supports transitioned Microsoft account users.
For more information about this transition, see Dynamics 365 Customer Engagement (on-premises) Integration with Office 365.
Authentication deep dive
The previous discussion introduced two simple approaches that can be used to authenticate a user with the Dynamics 365 Customer Engagement (on-premises) web services. The following information shows how to authenticate a user by using the IServiceManagement<TService>
class and includes the source code to the GetProxy
method.
To see the complete sample that contains the following examples, see Sample: Authenticate Office 365 Users. You will notice that authentication at this level takes a lot more code.
The following sample code demonstrates the classes and methods that you can use in your application to authenticate an Office 365/MOS user using the Dynamics 365 Customer Engagement (on-premises) web services.
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);
}
The code creates an IServiceManagement<TService> object for the Organization service. An object of type AuthenticationCredentials is used to contain the user’s sign-in credentials. The IServiceManagement
object and user credentials are then passed to GetProxy
to obtain the web service proxy reference.
/// <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 && provider.IdentityProviderType == IdentityProviderType.LiveId)
{
authCredentials.SupportingCredentials = new AuthenticationCredentials();
authCredentials.SupportingCredentials.ClientCredentials =
Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice();
}
}
break;
}
return authCredentials;
}
The AuthenticationCredentials object is configured according to the subscribed identity for the signed-in user. Notice that user credentials for all types of identity
providers are shown. The default case handles Office 365/MOS managed domain, online users whose identities are federated
in the cloud, and transitioned Microsoft account users. Now let’s take a look at what GetProxy
actually does.
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 });
}
For all deployments other than on-premises
(Active Directory, without claims), the Authenticate(AuthenticationCredentials) method is invoked and
then the service proxy is instantiated. Notice that the authentication credentials returned from Authenticate
contain the security token response that is used in the service
proxy constructor. The generic GetProxy
method shown previously can be used to obtain an object reference to either
OrganizationServiceProxy or
DiscoveryServiceProxy.
See also
Connect with Microsoft Office 365 and Dynamics 365 Customer Engagement (on-premises)
Sample: Authenticate Office 365 Users
Helper Code: ServerConnection Class
Active Directory and Claims-Based Authentication
Use connection strings in XRM tooling to connect to Dynamics 365 Customer Engagement (on-premises)