Delen via


Stapsgewijze handleiding: server-naar-server-verificatie voor één tenant

 

Gepubliceerd: januari 2017

Is van toepassing op: Dynamics 365 (online)

In deze stapsgewijze handleiding worden de stappen beschreven om multitenant webtoepassing te maken die verbinding kan maken met een Update voor Microsoft Dynamics 365 (online) - december 2016-tenant door middel van Microsoft Visual Studio 2015 MVC-webtoepassingssjabloon.

Vereisten

  • Visual Studio 2015 geïnstalleerd met de Web Developer-hulpmiddelen

  • Een Update voor Microsoft Dynamics 365 (online) - december 2016-tenant die is gekoppeld aan uw Azure Active Directory-tenant (Azure AD).

  • Een tweede Update voor Microsoft Dynamics 365 (online) - december 2016-tenant, die is gekoppeld aan een andere Azure AD-tenant. Deze tenant vertegenwoordigt een abonnee van uw toepassing. Dit kan een proefabonnement voor Update voor Microsoft Dynamics 365 (online) - december 2016 zijn.

Doel van dit overzicht

Als u deze stapsgewijze handleiding hebt doorlopen, hebt u een MVC-webtoepassing die gebruik maakt van de WhoAmIRequest Class om gegevens over de gebruiker op te halen waarmee de toepassing verbinding maakt met de Dynamics 365 (online)-tenant.

Wanneer de app correct wordt uitgevoerd, ziet u een opdracht Aanmelden in de rechterbovenhoek.

The sign in command in the app

Klik op de opdracht Aanmelden. U wordt omgeleid naar Azure AD om uw gegevens in te voeren.

Na het aanmelden ziet u een opdracht WhoAmI.

The WhoAmI command

Klik op WhoAmI. De volgende opties zouden zichtbaar moeten worden:

Results of a WhoAmI request

Als u een query uitvoert op de Dynamics 365-tenant, ziet u dat de resultaten die worden geretourneerd op het WhoAmI-bericht verwijzen naar een specifieke account van een toepassingsgebruiker, die u hebt geconfigureerd voor gebruik door de webtoepassing, in plaats van naar de gebruikersaccount die u zelf gebruikt.

De Azure AD-tenant verifiëren

Maak, voordat u begint, verbinding met uw Office 365-beheercentrumhttps://portal.office.com. Controleer in de vervolgkeuzelijst Admin centers dat zowel Dynamics 365 als Azure AD aanwezig zijn.

Admin Centers with Azure Active Directory and Dynamics 365

Als uw Azure AD-abonnement niet is gekoppeld aan een Dynamics 365-abonnement, bent u niet in staat om bevoegdheden voor uw toepassing te verlenen voor toegang tot Dynamics 365-gegevens.

Als u deze optie niet ziet, raadpleeg dan Register your free Azure Active Directory subscription voor uitleg over registratie voor een Azure AD-abonnement.

Als u al een Azure-abonnement hebt, maar dit niet is gekoppeld aan uw Microsoft Office 365-account, zie dan Associate your Office 365 account with Azure AD voor informatie over het maken en beheren van apps.

Een MVC-webtoepassing maken

Met behulp van Visual Studio 2015 kunt u een nieuwe MVC-webtoepassing maken en deze registreren in uw Azure AD-tenant.

  1. Open Visual Studio 2015.

  2. Zorg ervoor dat de Microsoft-account waarmee u bent aangemeld, dezelfde is als de account met toegang tot de Azure AD-tenant die u wilt gebruiken om uw toepassing te registreren.

  3. Klik op New Project en selecteer .NET Framework 4.6.1 en de sjabloon ASP.NET Web Application.

    Klik op OK en selecteer in het dialoogvenster Nieuw ASP.NET-project MVC.

  4. Klik op de knop Change Authentication en selecteer in het dialoogvenster Work And School Accounts.

  5. Selecteer in de vervolgkeuzelijst Cloud – Multiple Organizations.

    ASP.NET MVC Change Authentication Dialog

  6. Klik op OK en voltooi de initialisatie van het project.

    Notitie

    Als u op deze manier een Visual Studio-project aanmaakt, wordt de toepassing geregistreerd bij uw Azure AD-tenant en worden de volgende sleutels toegevoegd aan de 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=" /> 
    

Uw toepassing registreren bij Azure AD

Als u de stappen in Een MVC-webtoepassing maken hebt gevolgd, zou u moeten zien dat het webtoepassingsproject dat u in Visual Studio hebt aangemaakt, al in uw Azure AD-toepassingen is geregistreerd. Maar u moet nog één stap uitvoeren in de Azure AD-portal.

  1. Ga naar https://portal.azure.com en selecteer Azure Active Directory.

  2. Klik op App-registraties en zoek de toepassing u hebt aangemaakt in Visual Studio. Controleer in het gebied Algemeen de eigenschappen:

    Application registration data in Azure Active Directory

  3. Controleer of de eigenschap Toepassings-id overeenkomt met de waarde ClientId die is toegevoegd in uw Web.Config appSettings.

  4. De waarde voor URL van de startpagina moet overeenkomen met de eigenschap SSL URL in uw Visual Studio-project en moet doorleiden naar een localhost-URL, namelijk https://localhost:44392/.

    Notitie

    Wanneer u uw toepassing in een later stadium publiceert, moet u dit nog aanpassen. Op dit moment moet dit zijn ingesteld op de juiste localhost-waarde ten behoeve van foutopsporing.

  5. U moet uw toepassing rechten geven voor toegang tot Dynamics 365-gegevens. Klik in het gebied API-toegang op Vereiste machtigingen. U moet hier zien dat de toepassing al machtigingen heeft voor Windows Azure Active Directory.

  6. Klik op Toevoegen en vervolgens op Een API selecteren. Selecteer in de lijst Dynamics 365 en klik op de knop Selecteren.

  7. Selecteer in Machtigingen selecteren de optie Toegang tot Dynamics 365 verkrijgen als organisatiegebruikers. Klik vervolgens op de knop Selecteren.

  8. Klik op Gereed om deze machtigingen toe te voegen. Als u klaar bent, zou u moeten zien dat de bevoegdheden zijn toegepast:

    Dynamics 365 permissions applied to application in Azure Active Directory

  9. Controleer in het gebied API-toegang dat een Sleutel-waarde is toegevoegd. De waarde van Sleutel is niet zichtbaar in de Azure-portal nadat de toepassing is gemaakt, maar deze waarde is toegevoegd aan uw Web.Config appSettings als het ClientSecret.

Een toepassingsgebruiker maken

Maak volgens de stappen in Handmatig een Dynamics 365-toepassingsgebruiker maken een toepassingsgebruiker aan met de waarde van de Toepassings-ID uit uw toepassingregistratie, die ook identiek is aan de waarde van ClientId in de Web.Config.

Assembly’s toevoegen

Voeg de volgende NuGet-pakketten toe aan het project.

Pakket

Versie

Microsoft.CrmSdk.CoreAssemblies

Nieuwste versie

Microsoft.IdentityModel.Clients.ActiveDirectory

2.22.302111727

Microsoft.IdentityModel.Tokens

5.0.0

Microsoft.Azure.ActiveDirectory.GraphClient

2.1.0

Notitie

Werk de Microsoft.IdentityModel.Clients.ActiveDirectory-assembly's niet bij naar de nieuwste versie. In de versie 3.x van deze assembly’s is een interface gewijzigd waarvan de Microsoft.CrmSdk.CoreAssemblies afhankelijk is.

Voor informatie over het beheer van NuGet-pakketten raadpleegt u NuGet Documentation: Managing NuGet Packages Using the UI.

Codewijzigingen toepassen op de MVC-sjabloon

De volgende codewijzigingen leveren de basisfunctionaliteit voor gebruik van het Dynamics 365WhoAmI-bericht en verifiëren dat de identiteit van de toepassinggebruikersaccount door de toepassing wordt gebruikt.

Web.config

Voeg de volgende sleutels toe aan de appSettings.

<add key="ida:OrganizationHostName" value="https://{0}.crm.dynamics.com" /> 

Aan de tekenreeks ida:OrganizationHostName wordt de naam toegevoegd van de Dynamics 365 online-organisatie van de abonnee op de plaats van de tijdelijke aanduiding, zodat toegang wordt verkregen tot de juiste service.

<add key="owin:appStartup" value="<your app namespace>.Startup" />

De tekenreeks owin:appStartup zorgt ervoor dat de OWIN-middleware de klasse Startup gebruikt in dit project. Anders krijgt u het volgende foutbericht:

- No assembly found containing an OwinStartupAttribute.
- No assembly found containing a Startup or [AssemblyName].Startup class.

Zie voor meer informatie ASP.NET: OWIN Startup Class Detection.

Controllers/HomeController.cs

Voeg de decorator AllowAnonymous toe aan de actie Index. Hiermee kan toegang tot de standaardpagina worden verkregen zonder verificatie.

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();
        }
    }
}

Notitie

Er wordt vanuit gegaan dat u in uw webtoepassing of -service geen anonieme toegang toestaat. In dit voorbeeld wordt anonieme toegang gebruikt om alles overzichtelijk te houden. Hoe u toegang tot uw toepassing beheert, ligt buiten het bereik van deze stapsgewijze handleiding.

Views/Shared/_Layout.cshtml

Om de opdrachtkoppeling WhoAmI zichtbaar te maken voor geverifieerde gebruikers, moet u dit bestand bewerken.

Zoek het element div met de klasse navbar-collapse collapse en voeg hierin de onderstaande code toe:

<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

De volgende wijzigingen roepen het toestemmingsframework aan, wanneer een nieuwe tenant zich bij de toepassing aanmeldt:

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);
                  }
        }
       });

  }
 }

Controllers/CrmSdkController toevoegen

Voeg het volgende bestand CrmSdkController.cs toe aan de map Controllers. Deze code voert het bericht WhoAmI uit.

  1. Klik met de rechtermuisknop op de map Controllers en selecteer Toevoegen > Controller...

  2. Selecteer in het dialoogvenster Add Scaffold de optie MVC5 Controller - Empty.

  3. Klik op Toevoegen.

  4. Plak de volgende code in, en vervang hierin <Your app namespace> door de naamruimte van uw app.

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

Voeg een nieuwe weergave toe met de naam Index.

  1. Klik met de rechtermuisknop op de map CrmSdk en selecteer Toevoegen > Weergave...

  2. Stel in het dialoogvenster Weergave toevoegen de volgende waarden in:

    MVC Add View Dialog

  3. Klik op Toevoegen.

  4. Vervang de gegenereerde code door de onderstaande code:

    @model string
    @{
     ViewBag.Title = "SDK Connect";
    }
    
    
    <h2>@ViewBag.Title.</h2>
    
    <p>Connected and executed sdk command WhoAmI.</p>
    
    <p>Value: @Model</p>
    

Fouten opsporen in de toepassing

Wanneer u op F5 drukt om fouten op te sporen in de toepassing, wordt mogelijk in een foutbericht gemeld dat het certificaat voor toegang tot localhost met gebruik van SSL niet wordt vertrouwd. Hier volgen enkele koppelingen waarmee u dit probleem met Visual Studio en IIS Express kunt oplossen:

Notitie

Voor deze stap kunt u eenvoudig de Microsoft-account gebruiken die aan uw Azure AD-tenant is gekoppeld en de Dynamics 365-tenant die daaraan is gekoppeld. Hiermee wordt niet een multitenant-scenario gedemonstreerd. Dat gebeurt in de volgende stap. Deze stap is slechts bedoeld om te controleren dat de code functioneert, voordat extra complexiteit wordt geïntroduceerd waarmee de werkelijke multitenant-functionaliteit wordt getest.

Zie de stappen die in Doel van dit overzicht worden beschreven voor het testen van de toepassing.

Op dit moment kunt u verifiëren dat de toepassinggebruikersaccount is gebruikt. Een eenvoudige manier om dit te controleren is door middel van de web-API van Dynamics 365. Typ de onderstaande URL in een afzonderlijk tabblad of venster en vervang de UserId-waarde door de waarde van de toepassing.

[Organization URI]/api/data/v8.2/systemusers(<UserId value>)?$select=fullname

De JSON-respons zou moeten lijken op het volgende: Merk op dat de waarde van fullname de waarde is van de toepassingsgebruiker die u in de stap Een toepassingsgebruiker maken hebt gemaakt, in plaats van de Dynamics 365-gebruiker waarmee u zich bij de toepassing hebt aangemeld.

 {
     "@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"
 }

De testabonnee configureren

Nu u hebt gecontroleerd of de toepassing werkt, is het tijd om te testen of u verbinding kunt maken met een andere Dynamics 365 (online)-tenant. Wanneer u een andere Dynamics 365 (online)-organisatie gebruikt, moet u de volgende stappen uitvoeren.

Toestemming geven vanuit de abonnerende tenant

Om toestemming te geven, voert u de volgende stappen uit terwijl u bent aangemeld als de Azure AD-beheerder:

  1. Terwijl u foutopsporing in uw toepassing uitvoert, opent u een apart InPrivate-venster of incognitovenster.

  2. Voer in het adresveld van het venster de URL voor uw app in, dus https://localhost:44392/.

  3. Klik op de knop Aanmelden. U wordt gevraagd om toestemming te verlenen.

    Azure Active Directory consent form

Nadat u toestemming hebt gegeven, wordt u teruggeleid naar de app. U kunt deze nog niet gebruiken. Als u op dit moment klikt op WhoAmI, kunt u de volgende uitzondering verwachten:

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.

Door toestemming te geven, wordt de toepassing van uw Azure AD-tenant toegevoegd aan de toepassingen in de Active Directory-tenant van de abonnee.

Een aangepaste beveiligingsrol aanmaken in de abonnee-tenant

De toepassingsgebruiker die u moet maken, moet zijn gekoppeld aan een aangepaste beveiligingsrol die de bevoegdheden ervan bepaalt. Voor deze handmatige teststap moet u eerst handmatig een aangepaste beveiligingsrol maken.Meer informatie:TechNet: Een beveiligingsrol maken of bewerken

Notitie

De toepassingsgebruiker kan niet aan een van standaardbeveiligingsrollen van Dynamics 365 worden gekoppeld. U moet een aangepaste beveiligingsrol maken die u aan de toepassingsgebruiker kunt koppelen.

De toepassingsgebruiker voor de abonnee maken

In het kader van deze stapsgewijze handleiding wordt handmatig de toepassingsgebruiker gemaakt, waarmee het opzetten van een verbinding vanuit een andere tenant wordt gecontroleerd. Wanneer u de toepassing uitrolt naar de daadwerkelijke abonnees is het aan te raden om dit te automatiseren.Meer informatie:Een methode voorbereiden om de toepassingsgebruiker uit te rollen

U maakt de toepassingsgebruiker handmatig aan met gebruik van dezelfde waarden die u voor uw ontwikkelorganisatie in Een toepassingsgebruiker maken hebt gebruikt. De uitzondering hierop is dat u eerst de stap moet hebben voltooid voor het verlenen van toestemming. Wanneer u de gebruiker opslaat, worden de velden URI van toepassings-id en Object-id van Azure AD ingesteld. U kunt de gebruiker pas opslaan nadat u toestemming hebt verleend.

Koppel tenslotte de toepassingsgebruiker aan de aangepaste beveiligingsrol die u in de vorige stap hebt toegevoegd.

Test de verbinding voor de abonnee.

Herhaal de stappen in Fouten opsporen in de toepassing, maar gebruik nu referenties voor een gebruiker van de andere Dynamics 365-tenant.

Zie ook

Multitenant server-naar-server-verificatie gebruiken
Server-naar-server-verificatie voor één tenant gebruiken
Webtoepassingen bouwen met Server-naar-server-verificatie (S2S)
Verbinding maken met Microsoft Dynamics 365

Microsoft Dynamics 365

© 2017 Microsoft. Alle rechten voorbehouden. Auteursrecht