8

Birisi özniteliğimde listelenen bir rolün parçası olmadığında samimi bir ileti göstermek istiyorum. Şu anda benim uygulama sadece kullanıcı ekrana geri dönüyor. Ben sadece [AuthorizeAttribute] genişleyen bir özel özellik oluşturma hakkında konuşmak birkaç yazı okudum, ama bunu yapmak için kutunun dışında bir şey olması gerektiğini düşünüyorum.özniteliği

Birisi, lütfen kullanıcıyı oturum açma formuna göndermesini istemediğim doğru yere yönlendirebilir, sadece "yetkili olmayan" bir mesaj gönderebilir misiniz?

cevap

2

basitlik veya mantık toplam kontrolü size eylem yönteminde bu çağırabilirsiniz istediğini ise:

User.IsInRole("NameOfRole"); 

Bir bool döndüren ve o sonucun bağlı olarak mantık kalanını yapabilirsiniz. Bazı durumlarda kullandım

Başka biri:

System.Web.Security.Roles.GetRolesForUser(); 

Bunun bir dize [] döndüren düşünüyorum ama beni bu konuda teklif yok. bir örneği hep yardımcı ... Sürece döndürme türü "ActionResult" Kabul dönüş türleri (ViewResult, PartialViewResult, RedirectResult, JsonResult herhangi geri dönebilirler olduğu gibi

public ActionResult AddUser() 
{ 
    if(User.IsInRoles("SuperUser") 
    { 
     return View("AddUser"); 
    } 
    else 
    { 
     return View("SorryWrongRole"); 
    } 
} 

: DÜZENLEME

...)

+0

bu mantığı kullanarak kısmi görünümleri "arkadaş canlısı iletiler" ile düzeltmem gerekiyor mu? Tüm eylem yöntemini, aynı şeyi yapan bir özellik ile kaplamak mümkün değil mi? – Kyle

+0

Yukarıda bir örnek ekledim. Diğer seçeneğiniz elbette bahsettiğiniz gibi kendi özniteliklerinizi yazmanızdır (bu, en iyisi ünite testine rağmen en temiz olanı olacaktır), fakat bu kesinlikle kutu dışı bir yaklaşım değildir. –

0

Kutudan çıktığı davranış, [Authorize] özniteliğinin bir HTTP 401 döndürmesidir. FormsAuthenticationModule (varsayılan olarak yüklenir) bu 401'i engeller ve kullanıcıyı oturum açma sayfasına yönlendirir. Ne demek istediğimi görmek için Reflektörde System.Web.Security.FormsAuthenticationModule :: OnLeave'e bir göz atın. Eğer AuthorizeAttribute dönüş HTTP 401 dışında bir şey diğer yapmak istiyorsanız

, sen AuthorizeAttribute :: HandleUnauthorizedRequest yöntemini geçersiz ve orada özel mantığı gerçekleştirmek gerekir.

<forms loginUrl="~/Account/LogOn" timeout="2880" /> 

Ve ~/AccessDenied gibi farklı bir URL'ye yönlendirme yapmak: Alternatif olarak, sadece Web.config \ ~ bu kısmını değiştirin.

3

Birkaç gün önce bu soruna girdim ve çözüm biraz ayrıntılı ama burada önemli bitler. AuthorizeAttribute'da, OnAuthorization yönteminde, özel bir sonucu döndürmeyi biraz zorlaştıran yetkilendirme başarısız olduğunda HttpUnauthorizedResult yöntemi döndürülür.

Yaptığım şey bir CustomAuthorizeAttribute sınıfı oluşturmak ve bunun yerine bir istisna atmak için OnAuthorization yöntemini geçersiz kılmaktı. Özel bir hata işleyicisiyle bu özel durumu yakalayabilir ve 401'i (Yetkisiz) döndürmek yerine özelleştirilmiş bir hata sayfası görüntüleyebilirim.

<customErrors mode="On" defaultRedirect="~/Error"> 
     <error statusCode="401" redirect="~/Error/Unauthorized" /> 
     <error statusCode="404" redirect="~/Error/NotFound" /> 
    </customErrors> 

ve ardından özel sayfalar kadar hizmet için kendi ErrorController uygulamak:

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public virtual void OnAuthorization(AuthorizationContext filterContext) { 
     if (filterContext == null) { 
      throw new ArgumentNullException("filterContext"); 
     } 

     if (AuthorizeCore(filterContext.HttpContext)) { 
      HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache; 
      cachePolicy.SetProxyMaxAge(new TimeSpan(0)); 
      cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */); 
     } 
     else { 
      // auth failed, redirect to login page 
      // filterContext.Result = new HttpUnauthorizedResult(); 

      throw new HttpException ((int)HttpStatusCode.Unauthorized, "Unauthorized");     
     } 
    } 
} 

sonra web.config belirli hatalar için özel işleyicileri ayarlayabilirsiniz.

IIS7'de, özel hatalarınızı etkinleştirmek için Response.TrySkipIisCustomErrors = true; ayarlarına bakmanız gerekir.

6

$ 0.02 $ ekleyerek biraz geç olabilir, ancak CustomAuthorizationAttribue oluşturduğunuzda, AuthorizeAttribute.HandleUnauthorizedRequest yöntemini yönlendirir nerede dikte etmek için AuthorizationContext.Result property kullanabilirsiniz. İşte

bir kullanıcı başarısız bir yetkilendirme sonra gönderilmesi gerekmektedir URL'sini belirtmek sağlayan çok basit bir örnek:

public class Authorize2Attribute : AuthorizeAttribute 
{ 
    // Properties 

    public String RedirectResultUrl { get; set; } 

    // Constructors 

    public Authorize2Attribute() 
     : base() 
    { 
    } 

    // Overrides 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (String.IsNullOrEmpty(RedirectResultUrl)) 
      base.HandleUnauthorizedRequest(filterContext); 

     else 
      filterContext.Result = new RedirectResult(RedirectResultUrl); 
    } 
} 

Ve/Hata/Yetkisiz kullanıcıyı yönlendirmek istiyorsa önerildiği gibi bir önceki sonrası: crazyarabian için

[Authorize2(Roles = "AuthorizedUsers", RedirectResultUrl = "/Error/Unauthorized")] 
public ActionResult RestrictedAction() 
{ 
    // TODO: ... 
} 
+0

Benzer bir şey yaptım, ancak kullanıcının kimliğinin doğrulanıp doğrulanmadığını kontrol ediyorum. Bu, bir rolde bulunmadığı için kullanıcıları reddetmeme izin veriyor, ancak giriş yapmaları istenmiyor –

2

çok benzer, ancak kullanıcı aslında doğrulanmış ise sadece benim dizeye yönlendirir. Bu, özniteliğin, şu anda giriş yapmadıysa standart oturum açma sayfasına yönlendirmesine izin verir, ancak URL'ye erişmek için izinleri yoksa başka bir sayfaya yönlendirir.

public class EnhancedAuthorizeAttribute : AuthorizeAttribute 
{ 
    public string UnauthorizedUrl { get; set; } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     var redirectUrl = UnauthorizedUrl; 
     if (filterContext.HttpContext.User.Identity.IsAuthenticated && !string.IsNullOrWhiteSpace(redirectUrl)) 
     { 
      filterContext.Result = new RedirectResult(redirectUrl); 
     } 
     else 
     { 
      base.HandleUnauthorizedRequest(filterContext); 
     } 
    } 
}