2

Comment je peux faire l'authentification basée sur les rôles Azure dans le backend webapi. Je vois des tonnes d'exemples pour Asp.net MVC mais aucun pour webapi avec front-end comme Angular. J'ai hébergé mon site web développé en angulaire avec backend comme webapi et je l'ai hébergé sur Azure et activé le répertoire Authentification/autorisation en tant qu'Azure Active sur le site Azure. J'ai également fait la configuration pour l'application AD pour les rôles dans ses fichiers manifestes. Après avoir cliqué sur le site Web, je dois m'authentifier et, après authentification, rediriger vers mon site Web. Pendant le chargement de mon site Web, il appelle mon webapi et le jeton d'authentification avec les revendications est transmis à mon webapi. Dans webapi je vérifie InRole ou [Authorize (Roles = "admin")] et basé sur ce que je permets l'accès. Cependant, les rôles de jeton ne circulent pas par défaut. Donc, j'interroge l'API du graphe pour obtenir des rôles en extrayant l'information du jeton et je la passe au graphe api pour obtenir les rôles. Je fais une requête dans la classe Owin Startup pour récupérer le rôle, mais je ne suis pas en mesure d'obtenir le succès. Y at-il quelque chose de mal avec le code, S'il vous plaît aider. Le code est copié ci-dessous. J'aurais aussi pu utiliser la bibliothèque ADAL JS dans Angular pour m'authentifier avec AD mais je n'ai pas besoin de le faire car j'ai activé l'authentification sur le site web Azure en utilisant l'option "Authentification/Autorisation". La couche d'authentification sur le site Web effectuera la validation de tous les jetons et la transmettra à webapi.Comment faire l'autorisation basée sur les rôles dans Azure avec le backend webapi Asp.net et le front-end comme Angular

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.IdentityModel.Tokens; 
using System.Linq; 
using Microsoft.Owin.Security; 
using Microsoft.Owin.Security.ActiveDirectory; 
using Owin; 
using System.Security.Claims; 
using System.Net; 
using System.Web; 
using System.IO; 
using System.Net.Http; 
using System.Net.Http.Headers; 
using Microsoft.IdentityModel.Clients.ActiveDirectory; 
using Microsoft.Owin.Security.OAuth; 
using Microsoft.Azure.ActiveDirectory.GraphClient; 
using System.Threading.Tasks; 

namespace OneMap.Web 
{ 
    public partial class Startup 
    { 
     // Apply bearer token authentication middleware to Owin IAppBuilder interface. 
     private void ConfigureAuth(IAppBuilder app) 
     { 
      var tenantId = Common.Configuration.GetConfigurationSetting("ida:Tenant"); 
      // ADAL authentication context for our Azure AD tenant. 
      var authenticationContext = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(
       $"https://login.windows.net/{tenantId}", true, TokenCache.DefaultShared); 

      // Secret key that can be generated in the Azure portal to enable authentication of a 
      // specific application (in this case our Web API) against an Azure AD tenant. 
      var applicationKey = Common.Configuration.GetConfigurationSetting("ida:Password"); 



      // Root URL for Azure AD Graph API. 
      var azureGraphApiUrl = "https://graph.windows.net"; 
      var graphApiServiceRootUrl = new Uri(new Uri(azureGraphApiUrl), tenantId); 
      var clientId = Common.Configuration.GetConfigurationSetting("ida:ClientId"); 
      // Add bearer token authentication middleware. 
      app.UseWindowsAzureActiveDirectoryBearerAuthentication(
       new WindowsAzureActiveDirectoryBearerAuthenticationOptions 
       { 
        // The id of the client application that must be registered in Azure AD. 
        TokenValidationParameters = new TokenValidationParameters { ValidAudience = clientId }, 
        // Our Azure AD tenant (e.g.: contoso.onmicrosoft.com). 
        Tenant = tenantId, 
        Provider = new OAuthBearerAuthenticationProvider 
        { 
         // This is where the magic happens. In this handler we can perform additional 
         // validations against the authenticated principal or modify the principal. 
         OnValidateIdentity = async context => 
           { 
            try 
            { 
           // Retrieve user JWT token from request. 
           var authorizationHeader = context.Request.Headers["Authorization"]; 
             var userJwtToken = authorizationHeader.Substring("Bearer ".Length).Trim(); 

           // Get current user identity from authentication ticket. 
           var authenticationTicket = context.Ticket; 
             var identity = authenticationTicket.Identity; 

           // Credential representing the current user. We need this to request a token 
           // that allows our application access to the Azure Graph API. 
           var userUpnClaim = identity.FindFirst(ClaimTypes.Upn); 
             var userName = userUpnClaim == null 
           ? identity.FindFirst(ClaimTypes.Email).Value 
           : userUpnClaim.Value; 
             var userAssertion = new UserAssertion(
           userJwtToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName); 

           // Credential representing our client application in Azure AD. 
           var clientCredential = new ClientCredential(clientId, applicationKey); 

           // Get a token on behalf of the current user that lets Azure AD Graph API access 
           // our Azure AD tenant. 
           var authenticationResult = await authenticationContext.AcquireTokenAsync(
           azureGraphApiUrl, clientCredential, userAssertion).ConfigureAwait(false); 

           // Create Graph API client and give it the acquired token. 
           var activeDirectoryClient = new ActiveDirectoryClient(
           graphApiServiceRootUrl,() => Task.FromResult(authenticationResult.AccessToken)); 

           // Get current user groups. 
           var pagedUserGroups = 
           await activeDirectoryClient.Me.MemberOf.ExecuteAsync().ConfigureAwait(false); 
             do 
             { 
            // Collect groups and add them as role claims to our current principal. 
            var directoryObjects = pagedUserGroups.CurrentPage.ToList(); 
              foreach (var directoryObject in directoryObjects) 
              { 
               var group = directoryObject as Group; 
               if (group != null) 
               { 
              // Add ObjectId of group to current identity as role claim. 
              identity.AddClaim(new Claim(identity.RoleClaimType, group.ObjectId)); 
               } 
              } 
              pagedUserGroups = await pagedUserGroups.GetNextPageAsync().ConfigureAwait(false); 
             } while (pagedUserGroups != null); 
            } 
            catch (Exception e) 
            { 
             throw; 
            } 
           } 
        } 
       }); 
     } 
    } 
} 

Répondre

0

autant que je sache, la revendication roles seulement émis sous la id_token. Après avoir modifié le manifeste de l'application (référez-vous à here), vous pouvez utiliser le SPA obtenir le id_token et accéder à l'API Web en fonction des rôles via le id_token.

Et il n'est pas nécessaire d'utiliser l'authentification/autorisation puisque vous avez protégé l'API Web en utilisant le middleware Microsoft.Owin.Security.ActiveDirectory OWIN. Pour authentifier le SPA, vous pouvez vous référer à cette adresse: code sample.

+0

Merci Fei pour l'aide. J'essayais d'utiliser Authentification/autorisation au lieu d'utiliser la bibliothèque Angular ADAL, je pensais pourquoi devrais-je écrire du code supplémentaire si tout est fourni ici, mais dans ce rôle la revendication ne vient pas. Comme tu l'as dit, ça ne viendra qu'en id_token et je vais mettre en place ADAL pour angulaire. Il existe donc deux types de jeton (Access token et id_token). J'espère que j'obtiendra ID_Token en utilisant la bibliothèque angulaire d'Adal? –

+0

Lorsque nous protégeons l'application Web en activant la fonctionnalité d'authentification/autorisation, nous pouvons appeler l'API Web en utilisant des cookies et des jetons émis par ** autorisation simple **. Il n'est pas possible d'appeler l'API Web à l'aide de id_token émis par Azure AD. Et dans ce scénario, il ne prend pas en charge la revendication de rôles. La bonne solution est de protéger l'API web en utilisant le composant OWIN, et d'obtenir l'id_token contenant les informations sur les rôles en utilisant la bibliothèque angulaire adal et d'appeler l'API web en utilisant ce jeton. –