如何在不使用角色的情况下使用ASP.NET WebAPI实现基于声明的授权
发布时间:2020-12-15 19:05:03 所属栏目:asp.Net 来源:网络整理
导读:我有一个使用Claims的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
我有一个使用Claims的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; } } 在我的寄存器方法中,为SubjectId添加新数据: var user = new ApplicationUser() { UserName = model.UserName,SubjectId = 25,LocationId = 4 }; IdentityResult result = await UserManager.CreateAsync(user,model.Password); 有人可以帮助告诉我我现在可以在控制器级别以及在方法级别基于这个SubjectId限制对控制器的访问,类似这样: [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:UsersRichardGitHubabilitest-serverpackagesMicrosoft.AspNet.WebApi.Core.5.2.2libnet45System.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); } } 解决方法
如果您覆盖了授权属性,您可以实现。在你的情况下,应该是这样的:
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); } } 在您希望限制访问的控制器中,使用ClaimsAuthorize属性而不是正常Authorize: [ClaimsAuthorize( SubjectID = "1,2",LocationID = "5,6,7")] [RoutePrefix("api/Content")] public class ContentController : BaseController { .... } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- ASP.NET FileUpload:如何在选择文件后自动回复?
- asp.net-mvc – 如何在将控件传递给View后调试ASP.NET MVC
- asp.net – 如何在json结果上使用jquery选择器
- asp.net – RDLC报告>图表>如何垂直显示列名称/标题/标签(
- Webpack,asp.net核心,docker:使用dotnet调试或发布版本构建
- .resx本地化不能与ASP.Net一起使用 – C#
- asp.net-mvc – 如何将自定义数据属性和类添加到`@ Html.Ed
- asp.net – Javascript:为什么如果(假)?
- 更改ASP.NET网站管理工具连接字符串
- asp.net-mvc – 重置asp.net mvc路由而不重置应用程序