샘플: Microsoft Dynamics 365 웹 서비스를 사용하여 사용자 인증
게시 날짜: 2017년 1월
적용 대상: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online
이 샘플에서는 Microsoft Dynamics 365 배포를 사용하여 사용자를 인증하고 웹 서비스에 대한 참조를 가져오는 방법을 보여 줍니다. 이 샘플에는Microsoft Dynamics 365(온라인)에 프로비전된 Microsoft Office 365 사용자에 대한 지원이 포함됩니다.
Microsoft Dynamics CRM SDK 패키지를 다운로드합니다. 다운로드 패키지의 다음 위치에서 확인할 수 있습니다.
SDK\SampleCode\CS\GeneralProgramming\Authentication\AuthenticateWithNoHelp\AuthenticateWithNoHelp.cs
보여 주기
이 샘플에서는 Microsoft Dynamics 365(온라인 및 온-프레미스) 배포를 사용하여 사용자를 인증하고 웹 서비스를 호출하는 방법을 보여 줍니다. 이 샘플은 CrmServiceHelpers.cs 도우미 코드에 의존하지 않습니다. 도우미 코드를 사용하는 샘플은 샘플: Microsoft Dynamics 365용 빠른 시작을 참조하십시오.
예제
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Reflection;
// These namespaces are found in the Microsoft.Xrm.Sdk.dll assembly
// located in the SDK\bin folder of the SDK download.
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Discovery;
using Microsoft.Crm.Sdk.Messages;
namespace Microsoft.Crm.Sdk.Samples
{
/// <summary>
/// Demonstrate how to do basic authentication using IServiceManagement and SecurityTokenResponse.
/// </summary>
class AuthenticateWithNoHelp
{
#region Class Level Members
// To get discovery service address and organization unique name,
// Sign in to your CRM org and click Settings, Customization, Developer Resources.
// On Developer Resource page, find the discovery service address under Service Endpoints and organization unique name under Your Organization Information.
private String _discoveryServiceAddress = "https://dev.crm.dynamics.com/XRMServices/2011/Discovery.svc";
private String _organizationUniqueName = "OrganizationUniqueName";
// Provide your user name and password.
private String _userName = "username@mydomain.com";
private String _password = "password";
// Provide domain name for the On-Premises org.
private String _domain = "mydomain";
#endregion Class Level Members
#region How To Sample Code
/// <summary>
///
/// </summary>
public void Run()
{
IServiceManagement<IDiscoveryService> serviceManagement =
ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(
new Uri(_discoveryServiceAddress));
AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;
// Set the credentials.
AuthenticationCredentials authCredentials = GetCredentials(serviceManagement, endpointType);
String organizationUri = String.Empty;
// Get the discovery service proxy.
using (DiscoveryServiceProxy discoveryProxy =
GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials))
{
// Obtain organization information from the Discovery service.
if (discoveryProxy != null)
{
// Obtain information about the organizations that the system user belongs to.
OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy);
// Obtains the Web address (Uri) of the target organization.
organizationUri = FindOrganization(_organizationUniqueName,
orgs.ToArray()).Endpoints[EndpointType.OrganizationService];
}
}
if (!String.IsNullOrWhiteSpace(organizationUri))
{
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);
}
}
}
/// <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;
}
/// <summary>
/// Discovers the organizations that the calling user belongs to.
/// </summary>
/// <param name="service">A Discovery service proxy instance.</param>
/// <returns>Array containing detailed information on each organization that
/// the user belongs to.</returns>
public OrganizationDetailCollection DiscoverOrganizations(
IDiscoveryService service)
{
if (service == null) throw new ArgumentNullException("service");
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
RetrieveOrganizationsResponse orgResponse =
(RetrieveOrganizationsResponse)service.Execute(orgRequest);
return orgResponse.Details;
}
/// <summary>
/// Finds a specific organization detail in the array of organization details
/// returned from the Discovery service.
/// </summary>
/// <param name="orgUniqueName">The unique name of the organization to find.</param>
/// <param name="orgDetails">Array of organization detail object returned from the discovery service.</param>
/// <returns>Organization details or null if the organization was not found.</returns>
/// <seealso cref="DiscoveryOrganizations"/>
public OrganizationDetail FindOrganization(string orgUniqueName,
OrganizationDetail[] orgDetails)
{
if (String.IsNullOrWhiteSpace(orgUniqueName))
throw new ArgumentNullException("orgUniqueName");
if (orgDetails == null)
throw new ArgumentNullException("orgDetails");
OrganizationDetail orgDetail = null;
foreach (OrganizationDetail detail in orgDetails)
{
if (String.Compare(detail.UniqueName, orgUniqueName,
StringComparison.InvariantCultureIgnoreCase) == 0)
{
orgDetail = detail;
break;
}
}
return orgDetail;
}
/// <summary>
/// Generic method to obtain discovery/organization service proxy instance.
/// </summary>
/// <typeparam name="TService">
/// Set IDiscoveryService or IOrganizationService type to request respective service proxy instance.
/// </typeparam>
/// <typeparam name="TProxy">
/// Set the return type to either DiscoveryServiceProxy or OrganizationServiceProxy type based on TService type.
/// </typeparam>
/// <param name="serviceManagement">An instance of IServiceManagement</param>
/// <param name="authCredentials">The user's Microsoft Dynamics CRM logon credentials.</param>
/// <returns></returns>
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 });
}
#endregion How To Sample Code
#region Main method
/// <summary>
/// Standard Main() method used by most SDK samples.
/// </summary>
/// <param name="args"></param>
static public void Main(string[] args)
{
try
{
AuthenticateWithNoHelp app = new AuthenticateWithNoHelp();
app.Run();
}
catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp);
Console.WriteLine("Code: {0}", ex.Detail.ErrorCode);
Console.WriteLine("Message: {0}", ex.Detail.Message);
Console.WriteLine("Trace: {0}", ex.Detail.TraceText);
Console.WriteLine("Inner Fault: {0}",
null == ex.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
}
catch (System.TimeoutException ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine("Message: {0}", ex.Message);
Console.WriteLine("Stack Trace: {0}", ex.StackTrace);
Console.WriteLine("Inner Fault: {0}",
null == ex.InnerException.Message ? "No Inner Fault" : ex.InnerException.Message);
}
catch (System.Exception ex)
{
Console.WriteLine("The application terminated with an error.");
Console.WriteLine(ex.Message);
// Display the details of the inner exception.
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;
if (fe != null)
{
Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp);
Console.WriteLine("Code: {0}", fe.Detail.ErrorCode);
Console.WriteLine("Message: {0}", fe.Detail.Message);
Console.WriteLine("Trace: {0}", fe.Detail.TraceText);
Console.WriteLine("Inner Fault: {0}",
null == fe.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
}
}
}
// Additional exceptions to catch: SecurityTokenValidationException, ExpiredSecurityTokenException,
// SecurityAccessDeniedException, MessageSecurityException, and SecurityNegotiationException.
finally
{
Console.WriteLine("Press <Enter> to exit.");
Console.ReadLine();
}
}
#endregion Main method
}
}
참고 항목
Microsoft Dynamics 365에서 사용자 인증
도우미 코드: ServerConnection 클래스
Microsoft Dynamics 365(온라인) 웹 서비스를 사용하여 Office 365 사용자 인증
Microsoft Office 365 및 Microsoft Dynamics 365(온라인)에 연결
Microsoft Dynamics 365
© 2017 Microsoft. All rights reserved. 저작권 정보