gpt4 book ai didi

asp.net - 如何在不使用角色的情况下使用 ASP.NET Web API 实现基于声明的授权?

转载 作者:行者123 更新时间:2023-12-03 09:59:56 24 4
gpt4 key购买 nike

我有一个使用声明的 ASP.Net WebAPI 2 应用程序。声明作为两个附加列存储在标准 Identity2 AspNetUsers 表中:

CREATE TABLE [dbo].[AspNetUsers] (
[Id] INT IDENTITY (1, 1) NOT NULL,
....
[SubjectId] INT DEFAULT ((0)) NOT NULL,
[LocationId] INT DEFAULT ((0)) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);

我已经像这样修改了 ApplicationUser 类:
public class ApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager, string authenticationType)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
ClaimsIdentity userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
userIdentity.AddClaim(new Claim("SubjectId", this.SubjectId.ToString()));
userIdentity.AddClaim(new Claim("LocationId", this.LocationId.ToString()));
return userIdentity;
}

public int SubjectId { get; set; }
public int LocationId { get; set; }

}

在我的 register 方法中,我为 SubjectId 添加了新数据:
    var user = new ApplicationUser() { 
UserName = model.UserName,
SubjectId = 25,
LocationId = 4
};

IdentityResult result = await UserManager.CreateAsync(user, model.Password);

有人可以帮助我告诉我现在如何在 Controller 级别和方法级别限制对基于此 SubjectId 的 Controller 的访问,类似于以下内容:
[Authorize(SubjectId = "1,25,26")]
[RoutePrefix("api/Content")]
public class ContentController : BaseController
{

[Authorize(LocationId = "4")]
[Route("Get")]
public IQueryable<Content> Get()
{
return db.Contents;
}

[Authorize(SubjectId = "25")]
[Route("Get/{id:int}")]
public async Task<IHttpActionResult> Get(int id)
{
Content content = await db.Contents.FindAsync(id);
if (content == null)
{
return NotFound();
}
return Ok(content);
}

几个月以来,我一直在寻找一个示例,但除了对 ThinkTexture 产品的一些引用和以下链接之外,我一无所获

更新:
#region Assembly System.Web.Http.dll, v5.2.2.0
// C:\Users\Richard\GitHub\abilitest-server\packages\Microsoft.AspNet.WebApi.Core.5.2.2\lib\net45\System.Web.Http.dll
#endregion

using System;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace System.Web.Http
{
// Summary:
// Specifies the authorization filter that verifies the request's System.Security.Principal.IPrincipal.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : AuthorizationFilterAttribute
{
// Summary:
// Initializes a new instance of the System.Web.Http.AuthorizeAttribute class.
public AuthorizeAttribute();

// Summary:
// Gets or sets the authorized roles.
//
// Returns:
// The roles string.
public string Roles { get; set; }
//
// Summary:
// Gets a unique identifier for this attribute.
//
// Returns:
// A unique identifier for this attribute.
public override object TypeId { get; }
//
// Summary:
// Gets or sets the authorized users.
//
// Returns:
// The users string.
public string Users { get; set; }

// Summary:
// Processes requests that fail authorization.
//
// Parameters:
// actionContext:
// The context.
protected virtual void HandleUnauthorizedRequest(HttpActionContext actionContext);
//
// Summary:
// Indicates whether the specified control is authorized.
//
// Parameters:
// actionContext:
// The context.
//
// Returns:
// true if the control is authorized; otherwise, false.
protected virtual bool IsAuthorized(HttpActionContext actionContext);
//
// Summary:
// Calls when an action is being authorized.
//
// Parameters:
// actionContext:
// The context.
//
// Exceptions:
// System.ArgumentNullException:
// The context parameter is null.
public override void OnAuthorization(HttpActionContext actionContext);
}
}

最佳答案

如果您覆盖 Authorize,您可以实现这一点。属性。在你的情况下,它应该是这样的:

public class ClaimsAuthorize : AuthorizeAttribute
{
public string SubjectID { get; set; }
public string LocationID { get; set; }

protected override bool IsAuthorized(HttpActionContext actionContext)
{
ClaimsIdentity claimsIdentity;
var httpContext = HttpContext.Current;
if (!(httpContext.User.Identity is ClaimsIdentity))
{
return false;
}

claimsIdentity = httpContext.User.Identity as ClaimsIdentity;
var subIdClaims = claimsIdentity.FindFirst("SubjectId");
var locIdClaims = claimsIdentity.FindFirst("LocationId");
if (subIdClaims == null || locIdClaims == null)
{
// just extra defense
return false;
}

var userSubId = subIdClaims.Value;
var userLocId = subIdClaims.Value;

// use your desired logic on 'userSubId' and `userLocId', maybe Contains if I get your example right?
if (!this.SubjectID.Contains(userSubId) || !this.LocationID.Contains(userLocId))
{
return false;
}

//Continue with the regular Authorize check
return base.IsAuthorized(actionContext);
}
}

在您希望限制访问的 Controller 中,使用 ClaimsAuthorize属性而不是正常 Authorize一:
[ClaimsAuthorize(
SubjectID = "1,2",
LocationID = "5,6,7")]
[RoutePrefix("api/Content")]
public class ContentController : BaseController
{
....
}

关于asp.net - 如何在不使用角色的情况下使用 ASP.NET Web API 实现基于声明的授权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26806063/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com