如何使用Asp.net webapi后端和前端在Azure中进行基于角色的授权作为Angular
如何在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;
}
}
}
});
}
}
}
AFAIK,roles
索赔只在id_token中发布。在更改应用程序清单(请参阅here)之后,您可以使用SPA获取id_token,并根据角色通过id_token访问Web API。
由于您使用Microsoft.Owin.Security.ActiveDirectory
OWIN中间件保护了Web API,因此不需要使用认证/授权。要认证SPA,你可以参考这个code sample。
谢谢菲求救。我试图使用认证/授权,而不是使用Angular ADAL库,我想为什么我应该编写额外的代码,如果一切都在这里提供,但在这个角色索赔不来。正如你所说,它只会在id_token中出现,我将为角度实现ADAL。所以有两种类型的令牌(Access令牌和id_token)。我希望我会使用角色adal库得到ID_Token? –
当我们通过启用身份验证/授权功能来保护网络应用程序时,我们可以使用由** easy auth **发布的cookie和令牌来调用网络API。无法使用Azure AD发布的id_token调用Web API。在这种情况下,它不支持角色声明。正确的解决方案是使用OWIN组件保护Web API,并使用角色adal库获取包含角色信息的id_token,并使用此令牌调用Web API。 –