2

如何在webapi後端中執行基於Azure角色的身份驗證。我看到很多Asp.net MVC的例子,但沒有一個用於Angular的前端webapi。我將我的網站作爲webapi託管在後端,並將其託管在Azure上,並將身份驗證/授權作爲Azure網站中的Azure Active目錄啓用。此外,我已經完成AD應用程序的清單文件中的角色設置。在我訪問網站後,我必須進行身份驗證,然後在身份驗證後重定向到我的網站。在我的網站加載期間,它會調用我的webapi,並將帶有聲明的身份驗證令牌傳遞給我的webapi。在webapi中,我正在檢查InRole或[Authorize(Roles =「admin」)],並基於我允許訪問。但是,標記角色默認情況下不會流動。所以我通過從token中提取信息並將它傳遞給圖api來獲取角色來查詢圖api來獲取角色。我在Owin Startup類中進行查詢以獲取角色,但我無法獲得成功。代碼有什麼問題,請幫助。代碼複製如下。此外,我可以在Angular中使用ADAL JS庫來進行AD認證,但我不需要這樣做,因爲我已使用選項「認證/授權」在Azure網站中啓用了身份驗證。網站中的認證層將進行所有令牌驗證並將其轉發給webapi。如何使用Asp.net webapi後端和前端在Azure中進行基於角色的授權作爲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; 
            } 
           } 
        } 
       }); 
     } 
    } 
} 

回答

0

AFAIK,roles索賠只在id_token中發佈。在更改應用程序清單(請參閱here)之後,您可以使用SPA獲取id_token,並根據角色通過id_token訪問Web API。

由於您使用Microsoft.Owin.Security.ActiveDirectory OWIN中間件保護了Web API,因此不需要使用認證/授權。要認證SPA,你可以參考這個code sample

+0

謝謝菲求救。我試圖使用認證/授權,而不是使用Angular ADAL庫,我想爲什麼我應該編寫額外的代碼,如果一切都在這裏提供,但在這個角色索賠不來。正如你所說,它只會在id_token中出現,我將爲角度實現ADAL。所以有兩種類型的令牌(Access令牌和id_token)。我希望我會使用角色adal庫得到ID_Token? –

+0

當我們通過啓用身份驗證/授權功能來保護網絡應用程序時,我們可以使用由** easy auth **發佈的cookie和令牌來調用網絡API。無法使用Azure AD發佈的id_token調用Web API。在這種情況下,它不支持角色聲明。正確的解決方案是使用OWIN組件保護Web API,並使用角色adal庫獲取包含角色信息的id_token,並使用此令牌調用We​​b API。 –

相關問題