Guide pas-à-pas : authentification de serveur à serveur multi-utilisateurs
Date de publication : janvier 2017
S’applique à : Dynamics 365 (online)
Ce guide pas-à-pas décrira la procédure de création d'une application Web multi-utilisateurs qui peut se connecter à un client Mise à jour de décembre 2016 pour Microsoft Dynamics 365 (en ligne) à l'aide du modèle d'application Web MVC Microsoft Visual Studio 2015.
Configuration requise
Visual Studio 2015 avec les outils de développement Web installés
Un client Mise à jour de décembre 2016 pour Microsoft Dynamics 365 (en ligne) associé à votre client (Azure AD) Azure Active Directory.
Un deuxième client Mise à jour de décembre 2016 pour Microsoft Dynamics 365 (en ligne) associé à un autre client Azure AD. Ce client représente un abonnée à votre application. Il peut s'agir d'un abonnement Mise à jour de décembre 2016 pour Microsoft Dynamics 365 (en ligne) d'évaluation.
Objectif de cette procédure pas à pas
Lorsque vous terminerez ce guide pas-à-pas, vous aurez une application Web MVC qui utilisera WhoAmIRequest Class pour récupérer des données sur l'utilisateur que l'application utilise pour se connecter au client Dynamics 365 (en ligne).
Lorsque vous exécuterez l'application correctement, vous verrez une commande Se connecter dans l'angle supérieur droit.
Cliquez sur la commande Se connecter et vous serez dirigé vers Azure AD pour vos informations d'identification.
Une fois connecté, vous verrez qu'il existe une commande WhoAmI.
Cliquez sur WhoAmI, et vous devriez voir les éléments suivants :
Lorsque vous interrogerez votre client Dynamics 365, vous verrez que les résultats renvoyés par le message WhoAmI font référence à un compte d'utilisateur d'application spécifique que vous avez configuré pour l'application Web à utiliser plutôt que le compte d'utilisateur utilisé actuellement.
Vérifiez le client Azure AD
Avant de commencer, connectez-vous à votre Centre d'administration Office 365https://portal.office.com et dans le menu déroulant Centres d'administration, vérifiez que vous voyez Dynamics 365 et Azure AD.
Si votre abonnement Azure AD n'est pas associé à un abonnement Dynamics 365, vous ne pourrez pas accorder des privilèges pour que votre application accède aux données Dynamics 365.
Si vous ne voyez pas cette option, voir Souscrivez à votre abonnement Azure Active Directory gratuit pour savoir comment vous inscrire pour obtenir votre abonnement Azure AD.
Si vous avez déjà un abonnement Azure mais qu'il n'est pas associé à votre compte Microsoft Office 365, voir Associez votre compte Office 365 à Azure AD pour créer et gérer des applications.
Créer une application Web MVC
À l'aide de Visual Studio 2015, vous pouvez créer une application Web MVC et l'inscrire auprès de votre client Azure AD.
Ouvrez Visual Studio 2015.
Vérifiez que l'Compte Microsoft auquel vous êtes connecté est le même que celui ayant accès au client Azure AD que vous souhaitez utiliser pour enregistrer votre application.
Cliquez sur Nouveau projet et sélectionnez .NET Framework 4.6.1 et le modèle Application Web ASP.NET.
Cliquez sur OK, et dans la boîte de dialogue de projet Nouvel ASP.NET, sélectionnez MVC.
Cliquez sur le bouton Modifier l'authentification, puis dans la boîte de dialogue sélectionnez Comptes de travail et d'école.
Dans la liste déroulante, sélectionnez Nuage – plusieurs organisations.
Cliquez sur OK et complétez l'initialisation du projet.
Notes
La création du projet Visual Studio de cette façon permet d'inscrire l'application auprès de votre client Azure AD et d'ajouter les clés suivantes aux Web.Config appSettings :
<add key="ida:ClientId" value="baee6b74-3c39-4c04-bfa5-4414f3dd1c26" /> <add key="ida:AADInstance" value="https://login.microsoftonline.com/" /> <add key="ida:ClientSecret" value="HyPjzuRCbIl/7VUJ2+vG/+Gia6t1+5y4dvtKAcyztL4=" />
Inscrire votre application sur Azure AD
Si vous avez suivi les étapes de Créer une application Web MVC, vous devez trouver que le projet d'application Web que vous avez créé dans Visual Studio est déjà inscrit dans vos applications Azure AD. Mais il existe une étape supplémentaire à effectuer au sein du portail Azure AD.
Accédez à https://portal.azure.com et sélectionnez Azure Active Directory.
Cliquez sur Inscriptions d'application et recherchez l'application que vous avez créée à l'aide de Visual Studio. Dans la zone Général, vérifiez les propriétés :
Vérifiez que la propriété ID d'application correspond à la valeur ajoutée ClientId dans votre Web.Config appSettings.
La valeur URL de la page d'accueil doit correspondre à la propriété SSL URL de votre projet Visual Studio et doit diriger vers une URL localhost, c.-à-d. https://localhost:44392/.
Notes
Vous devrez modifier cela ultérieurement quand vous publierez réellement votre application. Mais vous avez besoin de définir la valeur localhost correcte pour le débogage.
Vous devez attribuer à vos privilèges d'application l'accès aux données Dynamics 365. Dans la zone Accès API, cliquez sur Autorisations requises. Vous devriez voir qu'il possède déjà des autorisations pour Windows Azure Active Directory.
Dans Ajouter, puis sur Sélectionner une API. Dans la liste, sélectionnez Dynamics 365, puis cliquez sur le bouton Sélectionner.
Dans Sélectionner les autorisations, sélectionnez Accéder à Dynamics 365 en tant qu'utilisateurs de l'organisation. Cliquez ensuite sur le bouton Sélectionner.
Cliquez sur Terminé pour ajouter ces autorisations. Lorsque vous avez terminé vous devez voir les autorisations appliquées :
Dans la zone Accès API, confirmez qu'une valeur Clé a été ajoutée. La valeur Clé n'est pas visible dans le portail d'Azure après que l'application a été créé, mais cette valeur a été ajoutée à votre Web.Config appSettings comme ClientSecret.
Créer un utilisateur d'application
À l'aide de la procédure de a77637f4-420a-4686-9084-d0288d9154af#bkmk_ManuallyCreateUser, créez un utilisateur d'application avec la valeur ID d'application de votre inscription d'application qui est la même que la valeur ClientId dans Web.Config.
Ajouter des assemblys
Ajouter les packages NuGet suivants à votre projet
Package |
Version |
---|---|
Microsoft.CrmSdk.CoreAssemblies |
Version la plus récente |
Microsoft.IdentityModel.Clients.ActiveDirectory |
2.22.302111727 |
Microsoft.IdentityModel.Tokens |
5.0.0 |
Microsoft.Azure.ActiveDirectory.GraphClient |
2.1.0 |
Notes
Ne mettez pas à jour les assemblys Microsoft.IdentityModel.Clients.ActiveDirectory vers la dernière version. La version 3.x de ces assemblys a été transformée en une interface dont Microsoft.CrmSdk.CoreAssemblies dépend.
Pour plus d'informations sur la gestion des packages NuGet, voir Documentation NuGet : Gestion des packages NuGet à l'aide de l'interface utilisateur
Appliquer des modifications du code au modèle MVC
Les modifications de code suivantes fourniront les fonctionnalités de base pour utiliser le message Dynamics 365WhoAmI et vérifier que l'identité du compte d'utilisateur de l'application est utilisée par l'application.
Web.config
Ajoutez les clés suivantes au appSettings.
<add key="ida:OrganizationHostName" value="https://{0}.crm.dynamics.com" />
La chaîne ida:OrganizationHostName aura le nom de l'organisation Dynamics 365 online de l'abonné ajouté à l'espace réservé afin que le service approprié soit accessible.
<add key="owin:appStartup" value="<your app namespace>.Startup" />
La chaîne owin:appStartup garantit que le logiciel intermédiaire OWIN utilise la classe Startup dans ce projet. Sinon le message d'erreur suivant s'affiche :
- No assembly found containing an OwinStartupAttribute.
- No assembly found containing a Startup or [AssemblyName].Startup class.
Informations complémentaires : ASP.NET : Détection de la classe de démarrage OWIN
Contrôleurs/HomeController.cs
Ajoutez le décorateur AllowAnonymous à l'action Index. Cela permet l'accès à la page par défaut sans authentification.
using System.Web.Mvc;
namespace SampleApp.Controllers
{
[Authorize]
public class HomeController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}
Notes
Dans votre application Web ou service, il n'est pas prévu que vous autorisiez un accès anonyme. L'accès anonyme est utilisé ici à des fins de simplicité. Le contrôle de l'accès à votre application sort de l'étendue de ce guide pas-à-pas.
Vues/Shared/_Layout.cshtml
Afin d'afficher le lien de commande WhoAmI pour les utilisateurs authentifiés, vous devez modifier ce fichier.
Recherchez l'élément div avec la classe navbar-collapse collapse et modifiez-le de manière à inclure le code ci-dessous :
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
@if (Request.IsAuthenticated)
{
<li>@Html.ActionLink("WhoAmI", "Index", "CrmSdk")</li>
}
</ul>
@Html.Partial("_LoginPartial")
</div>
App_Start/Startup.Auth.cs
Les modifications suivantes appelleront l'infrastructure de consentement lorsqu'un nouveau client se connectera à l'application :
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private string appKey = ConfigurationManager.AppSettings["ida:ClientSecret"];
//Not used
//private string graphResourceID = "https://graph.windows.net";
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private string authority = aadInstance + "common";
private ApplicationDbContext db = new ApplicationDbContext();
//Added
private string OrganizationHostName = ConfigurationManager.AppSettings["ida:OrganizationHostName"];
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions { });
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
/*
instead of using the default validation
(validating against a single issuer value, as we do in line of business apps),
we inject our own multitenant validation logic
*/
ValidateIssuer = false,
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
SecurityTokenValidated = (context) =>
{
return Task.FromResult(0);
},
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(clientId, appKey);
string tenantID = context
.AuthenticationTicket
.Identity
.FindFirst("https://schemas.microsoft.com/identity/claims/tenantid")
.Value;
/* Not used
string signedInUserID = context
.AuthenticationTicket
.Identity
.FindFirst(ClaimTypes.NameIdentifier)
.Value;
*/
//Added
var resource = string.Format(OrganizationHostName, '*');
//Added
Uri returnUri = new Uri(
HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)
);
/* Changed below
AuthenticationContext authContext =
new AuthenticationContext(
aadInstance + tenantID,
new ADALTokenCache(signedInUserID)
);
*/
//Changed version
AuthenticationContext authContext =
new AuthenticationContext(aadInstance + tenantID);
/* Changed below
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code,
new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)),
credential,
graphResourceID);
*/
//Changed version
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code,
new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)),
credential,
resource);
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
context.OwinContext.Response.Redirect("/Home/Error");
context.HandleResponse(); // Suppress the exception
return Task.FromResult(0);
}
}
});
}
}
Ajouter Controllers/CrmSdkController
Ajoutez le fichier CrmSdkController.cs suivant au dossier Controllers. Ce code exécutera le message WhoAmI
Cliquez avec le bouton droit sur le dossier Controllers et le sélectionnez Ajouter > Contrôleur…
Dans la boîte de dialogue Ajouter une structure, sélectionnez Contrôleur MVC5 – vide
Cliquez sur Ajouter
Collez le code suivant en substituant <Your app namespace> par l'espace de noms de votre application.
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.WebServiceClient;
using System; using System.Configuration;
using System.Linq;
using System.Security.Claims;
using System.Web.Mvc;
namespace <Your app namespace>
{
[Authorize]
public class CrmSdkController : Controller
{
private string clientId =
ConfigurationManager.AppSettings["ida:ClientId"];
private string authority =
ConfigurationManager.AppSettings["ida:AADInstance"] + "common";
private string aadInstance =
ConfigurationManager.AppSettings["ida:AADInstance"];
private string OrganizationHostName =
ConfigurationManager.AppSettings["ida:OrganizationHostName"];
private string appKey =
ConfigurationManager.AppSettings["ida:ClientSecret"];
// GET: CrmSdk
public ActionResult Index()
{
string tenantID = ClaimsPrincipal
.Current
.FindFirst("https://schemas.microsoft.com/identity/claims/tenantid")
.Value;
// Clean organization name from user logged
string organizationName = User.Identity.Name.Substring(
User.Identity.Name.IndexOf('@') + 1,
User.Identity.Name.IndexOf('.') - (User.Identity.Name.IndexOf('@') + 1)
);
//string crmResourceId = "https://[orgname].crm.microsoftonline.com";
var resource = string.Format(OrganizationHostName, organizationName);
// Request a token using application credentials
ClientCredential clientcred = new ClientCredential(clientId, appKey);
AuthenticationContext authenticationContext =
new AuthenticationContext(aadInstance + tenantID);
AuthenticationResult authenticationResult =
authenticationContext.AcquireToken(resource, clientcred);
var requestedToken = authenticationResult.AccessToken;
// Invoke SDK using using the requested token
using (var sdkService =
new OrganizationWebProxyClient(
GetServiceUrl(organizationName), false)
)
{
sdkService.HeaderToken = requestedToken;
OrganizationRequest request = new OrganizationRequest() {
RequestName = "WhoAmI"
};
OrganizationResponse response = sdkService.Execute(request);
return View((object)string.Join(",", response.Results.ToList()));
}
}
private Uri GetServiceUrl(string organizationName)
{
var organizationUrl = new Uri(
string.Format(OrganizationHostName, organizationName)
);
return new Uri(
organizationUrl +
@"/xrmservices/2011/organization.svc/web?SdkClientVersion=8.2"
);
}
}
}
Views/CrmSdk
Ajoutez une nouvelle vue nommée Index.
Cliquez avec le bouton droit sur le dossier CrmSdk et le sélectionnez Ajouter > Afficher…
Dans la boîte de dialogue Ajouter la vue, définissez les valeurs suivantes :
Cliquez sur Ajouter
Remplacez le code généré par ce qui suit :
@model string @{ ViewBag.Title = "SDK Connect"; } <h2>@ViewBag.Title.</h2> <p>Connected and executed sdk command WhoAmI.</p> <p>Value: @Model</p>
Déboguer l'application
Lorsque vous appuyez sur F5 pour déboguer l'application vous pouvez obtenir une erreur indiquant que le certificat accédant à localhost à l'aide du protocole SSL n'est pas approuvé. Voici quelques liens pour résoudre ce problème avec Visual Studio et IIS Express :
Notes
Pour cette étape, il suffit d'utiliser l'Compte Microsoft associé à votre client Azure AD et au client Dynamics 365 auquel il est associé. Cela ne représente pas réellement un scénario à multi-utilisateurs. Nous verrons cela à l'étape suivante. Cette étape sert uniquement à vérifier que le code s'exécute avant d'introduire la complexité supplémentaire visant à tester la fonctionnalité multi-utilisateurs réelle.
Reportez-vous aux étapes décrites dans Objectif de cette procédure pas à pas pour tester l'application.
À ce stade, vérifiez que le compte d'utilisateur de l'application a été utilisé. Une méthode simple pour vérifier cela consiste à utiliser l'API Web Dynamics 365. Tapez l'URL suivante dans un onglet ou une fenêtre distincte, en substituant la valeur UserId de l'application.
[Organization URI]/api/data/v8.2/systemusers(<UserId value>)?$select=fullname
La réponse JSON doit être identique à la suivante. Notez que la valeur fullname sera définie sur l'application que vous avez créée à l'étape Créer un utilisateur d'application, plutôt que sur l'utilisateur Dynamics 365 que vous avez utilisé pour vous connecter dans l'application.
{
"@odata.context": "[Organization Uri]/api/data/v8.2/$metadata#systemusers(fullname)/$entity",
"@odata.etag": "W/\"603849\"",
"fullname": "S2S User",
"systemuserid": "31914b34-be8d-e611-80d8-00155d892ddc",
"ownerid": "31914b34-be8d-e611-80d8-00155d892ddc"
}
Configurer l'abonné de test
Maintenant que vous avez vérifié si l'application fonctionne, il est temps de tester la connectivité à un client Dynamics 365 (en ligne) différent. En utilisant une autre organisation Dynamics 365 (en ligne) vous devez procéder comme suit.
Donner son consentement depuis le client s'abonnant
Pour donner son consentement, suivez les étapes suivantes lorsque vous êtes connecté en tant qu'administrateur Azure AD :
Lorsque vous déboguez votre application, ouvrez une fenêtre InPrivate ou incognito distincte.
Dans le champ d'adresse de la fenêtre, tapez l'URL de votre application, c'est-à-dire https://localhost:44392/.
Cliquez sur le bouton Se connecter et vous serez invité à accorder votre consentement.
Après avoir accordé votre consentement vous reviendrez à l'application, mais vous ne pourrez pas encore l'utiliser. Si vous cliquez sur WhoAmI à ce stade vous pouvez vous attendre à l'exception suivante :
System.ServiceModel.Security.MessageSecurityException
HResult=-2146233087
Message=The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Bearer authorization_uri=https://login.windows.net/4baaeaaf-2771-4583-99eb-7c7e39aa1e74/oauth2/authorize, resource_id=https://<org name>.crm.dynamics.com/'.
InnerException.Message =The remote server returned an error: (401) Unauthorized.
En accordant votre consentement, l'application de votre client Azure AD sera ajoutée aux applications dans le client Active Directory de l'abonné.
Créer un rôle de sécurité personnalisé dans le client de l'abonné
L'utilisateur de l'application que vous devrez créer doit être associé à un rôle de sécurité personnalisé qui définit leurs privilèges. Pour cette étape de test manuelle, vous devez d'abord créer manuellement un rôle de sécurité personnalisé.Pour plus d'informations :TechNet : Création ou modification d'un rôle de sécurité
Notes
L'utilisateur de l'application ne peut pas être associé à l'un des rôles de sécurité Dynamics 365 par défaut. Vous devez créer un rôle de sécurité personnalisé à associer à l'utilisateur de l'application.
Créer l'utilisateur d'application de l'abonné
Dans le cadre de ce guide pas-à-pas, nous allons créer manuellement l'utilisateur de l'application pour vérifier la connectivité d'un client différent. Lorsque vous déploierez vers des abonnés réels, vous souhaiterez automatiser cela.Pour plus d'informations :a77637f4-420a-4686-9084-d0288d9154af#bkmk_PrepareMethodToDeployAppUser
Vous créez l'utilisateur de l'application manuellement en utilisant les mêmes valeurs que vous avez utilisées pour votre organisation de développement dans Créer un utilisateur d'application. L'exception est que vous devez avoir terminé l'étape pour accorder votre consentement en premier. Lorsque vous enregistrez l'utilisateur, les valeurs URI de l'ID d'application et ID d'objet Azure AD seront définies. Vous ne pourrez pas enregistrer l'utilisateur si vous n'avez pas accordé votre consentement en premier.
Enfin, associez l'utilisateur de l'application au rôle de sécurité personnalisé que vous avez ajoutés à l'étape précédente.
Tester la connexion de l'abonné
Répétez la procédure décrite dans Déboguer l'application à l'exception de l'utilisation des informations d'identification d'un autre client Dynamics 365.
Voir aussi
Utilisez l'authentification de serveur à serveur multi-utilisateurs
Utilisez l'authentification de serveur à serveur mono-utilisateur
Créer des applications Web en utilisant l'authentification de serveur à serveur (S2S)
Connexion à Microsoft Dynamics 365
Microsoft Dynamics 365
© 2017 Microsoft. Tous droits réservés. Copyright