27

Talepler kullanan bir ASP.Net WebAPI 2 Uygulamanız var. iddialar standart Identity2 AspNetUsers tabloda iki ek sütun olarak saklanır: Benim kayıt yönteminde ASP.NET WebAPI ile İstemler Tabanlı Yetkilendirmeyi Rolleri kullanmadan nasıl uygularım?

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; } 

    } 

Ben SubjectId için yeni verilerde ekleyin: Böyle ApplicationUser sınıfını değiştirdiniz

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) 
); 

:

var user = new ApplicationUser() { 
     UserName = model.UserName, 
     SubjectId = 25, 
     LocationId = 4 
    }; 

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

birisi şimdi kontrolör düzeyinde bu SubjectId üzerinde ve ayrıca yöntemine dayalı bir denetleyiciye erişimi kısıtlama hakkında gitmek nasıl söyle yardımcı olabilir Buna benzer bir şey ile seviye: Aylardır

[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); 
    } 

şimdi ThinkTexture ürüne bazı referans dışındaki bir örnek arayan ancak edilmiş ve aşağıdaki linki buldum şey

Güncelleme:

#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); 
    } 
} 

cevap

34

Authorize özniteliğini geçersiz kılarsanız bunu başarabilirsiniz.

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); 
    } 
} 

Kumandanızda olarak yerine normal bir Authorize birinin ClaimsAuthorize özelliğini kullanın erişimi kısıtlamak isteyen: Senin durumunda böyle bir şey olmalı için

[ClaimsAuthorize(
    SubjectID = "1,2", 
    LocationID = "5,6,7")] 
[RoutePrefix("api/Content")] 
public class ContentController : BaseController 
{ 
    .... 
} 
+0

Çok teşekkürler senin Cevap. Alternatif ve iki yetki seviyesine sahip olmayı nasıl başarabileceğime dair tavsiyede bulunabilir misiniz? Benim soruma göre iki tür iddiadan bahsediyorum. SubjectId ve aynı zamanda LocationId iddiaları. Ne kadar öneride bulunduğunu görüyorsun ama iki farklı ClaimsAuthorize türüne sahip olsaydım bunu nasıl yapabileceğimi bilmiyorum. –

+0

@marifemac Bunu yine de bir öznitelik ile yapabilirsiniz, bana birkaç dakika verin cevabı düzenleyeyim. –

+0

@marifemac Düzenlendi, sorunuza daha iyi cevap veriyor mu? –