2014-11-20 27 views
7

.NET, MVC & Kimlik Çerçevesinde yeni. Kimlik çerçevesinin, ek denetimler yoluyla bireysel denetleyici eylemlerini güvenceye almasına izin verdiğini fark ettim.İzin temelli yetkilendirme. Net kimlik

[Authorize] 
public ActionResult Edit(int? Id){ 
    //edit action 
} 

Kullanıcı izinlerine göre belirli eylemleri güvenceye almak istiyorum.

Örnek: Sadece blog yayınını oluşturan kullanıcının düzenleyebileceği bir blog uygulaması.

Bunu düşünerek, aşağıdaki seçeneklerden herhangi birini gerçekleştirmek mümkün mü? Eğer öyleyse, en iyi nasıl elde edileceğine dair kaynaklar ve örnekler var mı?

[Authorize(Entity = "Entry", Permission = "Edit", Id = Id)] 
public ActionResult Edit(int? Id){ 
    //edit action 
} 

veya blog Id istekten yakalanır

[BlogEntryPermission(Permission = "Edit", Id = Id)] 
public ActionResult Edit(int? Id){ 
    //edit action 
} 

.

İzin temelli kimlik doğrulamasıyla ilgili her türlü bilgi veya yön, en çok takdir edilecektir. Yardımlarınız için şimdiden teşekkür ederiz.

[AuthorizeEntryPermission(Permission = "Edit")] 
public ActionResult Edit(int? Id){ 
    //edit action 
} 

cevap

6

Sen özel AuthorizationAttribute uygulayabilir. Rolleri ihtiyaç duyduğunuz kadar ayrıntılı hale getirebilirsiniz - aslında onları izinler gibi yapmak. Örneğin, gibi rol isimleri yapabiliriz:

  • EditBlogPost
  • AddBlogPost
  • ViewBlogPost

Sonra AuthorizeAttribute yerleşik kullanarak Kumandanızda roller ayarlayabilirsiniz.

[Authorize(Roles = "AddBlogPost")] 
public ActionResult Add(){ 
    //add action 
} 

[Authorize(Roles = "AddBlogPost")] 
[HttpPost] 
public ActionResult Add(BlogModel model){ 
    //add action 
} 

[Authorize(Roles = "EditBlogPost")] 
public ActionResult Edit(int? Id){ 
    //edit action 
} 

[Authorize(Roles = "EditBlogPost")] 
[HttpPost] 
public ActionResult Edit(BlogModel model){ 
    //edit action 
} 

[Authorize(Roles = "ViewBlogPost")] 
public ActionResult View(){ 
    //view action 
} 

Daha sonra, veritabanınızdaki her bir kullanıcıya farklı roller atamanız yeterlidir.

+0

için teşekkürler yön.Şimdi yol değişkenine erişmeye çalışırken bir sorunla karşılaşıyorum. var id = httpContext.Request.Form ["BlogId"]; Bu şekilde tanımlanan yol paramları için çalışmaz:/BlogPost/Edit/1. Bu değişkene erişmenin temiz bir yolu var mı? context.Request.RequestContext.RouteData.Values.ElementAt (2) .Value çalışır, ancak emin değilim güvenmek istediğim bir şey. – mcroteau

+1

@croteau Kullanabilirsiniz context.Request.RequestContext.RouteData.Values ​​["Id"] ' –

1

MVC sahiptir roller yerleşik: Eğer parametrelerini belirlemek ve bu gibi kullanmak Sonra

public class AuthorizeEntryPermission : AuthorizeAttribute 
{ 
     public string Permission { get; set; } 

     public AuthorizeEntryPermission(){ 
     } 

     public AuthorizeEntryPermission(string Permission) 
     { 
      this.Permission = Permission; 
     } 

     protected override bool AuthorizeCore(HttpContextBase httpContext) 
     { 
      var id = context.Request.RequestContext.RouteData.Values["Id"]; 
      //check your permissions 
     } 

     public override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      if (AuthorizeCore(filterContext.HttpContext)) 
      { 
       // ** IMPORTANT ** 
       // Since we're performing authorization at the action level, the authorization code runs 
       // after the output caching module. In the worst case this could allow an authorized user 
       // to cause the page to be cached, then an unauthorized user would later be served the 
       // cached page. We work around this by telling proxies not to cache the sensitive page, 
       // then we hook our custom authorization code into the caching mechanism so that we have 
       // the final say on whether a page should be served from the cache. 

       HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache; 
       cachePolicy.SetProxyMaxAge(new TimeSpan(0)); 
       cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */); 
      } 
      else 
      { 
       //handle no permission 
      } 
     } 

     private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus) 
     { 
      validationStatus = OnCacheAuthorization(new HttpContextWrapper(context)); 
     } 
    } 

istek

bir blogId alabileceğiniz

+2

Bu yaklaşıma dikkat etmelisiniz. Çerez limitine maksimum bir boyut vardır. Büyük bir uygulamada binlerce granül rolünüz olabilir – Shoe

+0

İyi nokta. Ancak, OP bir blog için izin istediğini söyledi - yönetecek pek çok kontrolörün olmadığını ima etti. Ancak, çok sayıda izin varsa, AuthorizeAttribute uygulamasını özelleştirmenin daha iyi bir yol olacağını kabul ediyorum. – NightOwl888

+0

@Shoe - Aslında, kesinlikle çerezin içindeki rolleri saklamak zorunda değilsiniz. Her istek için bunları yüklemek veya kullanıcı başına önbelleğe almak için kurabilirsiniz. Ya da rolleri bitwise ID'lerle ayarlayabilirsiniz, böylece çerezde saklamanız gereken tek şey uzun bir sayıdır. – NightOwl888

1

Umarım probleminiz şimdiye kadar çözüldü. Ama buna yeni bir çözüm eklemek için buna değer. Microsoft Identity 2 üyelik sistemi için İzin tabanlı uzantı uyguladık. Bu açık kaynak projesi var ve burada deposuna erişebilir:

https://github.com/Arminkhodaei/Identity-Permission-Extension

Kullanımı:

İlk yaklaşım:

// GET: /Manage/Index 
[AuthorizePermission(Name = "Show_Management", Description = "Show the Management Page.")] 
public async Task<ActionResult> Index(ManageMessageId? message) 
{ 
    //... 
} 

İkinci yaklaşım:

// GET: /Manage/Users 
public async Task<ActionResult> Users() 
{ 
    if (await HttpContext.AuthorizePermission(name: "AllUsers_Management", description: "Edit all of the users information.")) 
    { 
     return View(db.GetAllUsers()); 
    } 
    else if (await HttpContext.AuthorizePermission(name: "UnConfirmedUsers_Management", description: "Edit unconfirmed users information.")) 
    { 
     return View(db.GetUnConfirmedUsers()); 
    } 
    else 
    { 
     return View(new List<User>()); 
    } 
} 
+0

Merhaba Armin, Bu AuthorizePermission özniteliğini denetleyici düzeyinde kullanabilir miyim? – Alienalone

+0

Merhaba, @Alienalone, Tabii ki yapabilirsin. Daha fazla talimat ve açıklama almak için belgelerin ** Kullanım ** bölümünü inceleyebilirsiniz. –

+0

Teşekkürler. Denedim ve benim için mükemmel çalışıyor. Tekrar teşekkürler – Alienalone