2010-03-24 10 views
20

Chcę, aby [Authorize] przekierować do loginUrl, chyba że używam również roli, takiej jak [Authorize (Roles="Admin")]. W takim przypadku chcę po prostu wyświetlić stronę z informacją, że użytkownik nie jest autoryzowany.Jak przekierować [Autoryzuj] na loginUrl tylko wtedy, gdy role nie są używane?

Co należy zrobić?

+0

zadałem to samo pytanie tutaj: http://stackoverflow.com/questions/2322366/how-do -i-serve-up-a-nieautoryzowane-strony-kiedy-użytkownik-nie-jest-w-autoryzowanych-rolach –

+1

Robert: Dzięki. Szukałem podobnych postów przed opublikowaniem, ale nie widziałem twojego. Z którym rozwiązaniem skorzystałeś? – royco

+2

Zakończyłem przetasowanie własnego atrybutu 'AuthorizeRoles', używając kodu z' AuthorizeAttribute' i jego modyfikacji. Jeśli możesz poczekać do jutra, opublikuję kod. –

Odpowiedz

24

Oto kod z mojej zmodyfikowanej implementacji AuthorizeAttribute; Nazwałem to SecurityAttribute. Jedyną rzeczą, która mi się zmieniło to metoda OnAuthorization i dodałem dodatkową właściwość ciąg adresu URL przekierować do nieautoryzowanego stronie:

// Set default Unauthorized Page Url here 
private string _notifyUrl = "/Error/Unauthorized"; 

public string NotifyUrl { 
    get { return _notifyUrl; } set { _notifyUrl = value; } 
} 

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

    /// This code added to support custom Unauthorized pages. 
    else if (filterContext.HttpContext.User.Identity.IsAuthenticated) 
    { 
     if (NotifyUrl != null) 
      filterContext.Result = new RedirectResult(NotifyUrl); 
     else 
      // Redirect to Login page. 
      HandleUnauthorizedRequest(filterContext); 
    } 
    /// End of additional code 
    else 
    { 
     // Redirect to Login page. 
     HandleUnauthorizedRequest(filterContext); 
    } 
} 

to nazwać tak samo jak oryginalny AuthorizeAttribute, chyba że jest dodatkową właściwość, aby zastąpić nieautoryzowanemu URL strony:

// Use custom Unauthorized page: 
[Security (Roles="Admin, User", NotifyUrl="/UnauthorizedPage")] 

// Use default Unauthorized page: 
[Security (Roles="Admin, User")] 
+0

Dzięki, to działa dobrze. Zamiast modyfikować AuthorizeAttribute.cs, po prostu odziedziczyłem po nim. Teraz mogę używać Role z [Authorize], a mój kod zostanie znacznie uproszczony. Dzięki jeszcze raz. – royco

+0

Robert: Muszę wywołać HandleUnauthorizedRequest (filterContext) z poziomu AuthorizeCore, gdzie filterContext nie jest dostępny. Mogę po prostu przekazać filterContext do intrantu AuthorizeCore z filterContext.HttpContext. Myśli? – royco

+0

@Bob: AuthorizeCore to tylko lokalna metoda, więc powinieneś móc robić, co chcesz. –

3

Najprostszy sposób, jaki znalazłem, polega na rozszerzeniu i dostosowaniu AuthorizeAttribute tak, aby zrobił coś innego (tj. Nie ustawił HttpUnauthorizedResult), gdy sprawdzanie ról nie powiedzie się. Napisałem o tym na moim blogu article, który może ci się przydać. Artykuł opisuje to, czego potrzebujesz, ale idzie dalej i pozwala użytkownikowi, który "posiada" dane, na dostęp do akcji. Myślę, że modyfikacja powinna być dość łatwa do twoich celów - wystarczy usunąć część "lub właściciela".

+0

Odpowiedzi dotyczące wyłącznie linku są mile widziane, ponieważ jeśli łącze nie działa, odpowiedź staje się bezużyteczna, należy podać treść linku w odpowiedzi tutaj. –

+1

Odpowiedź dotyczy mojego własnego wpisu na blogu i opisuje ogólne podejście - i dlatego nie jest odpowiedzią "tylko link". Nie widzę potrzeby replikowania całego postu tutaj. – tvanfosson

13

rozszerzyć klasę AuthorizeAttribute i zastąpić HandleUnauthorizedRequest

public class RoleAuthorizeAttribute : AuthorizeAttribute 
{ 
    private string redirectUrl = ""; 
    public RoleAuthorizeAttribute() : base() 
    { 
    } 

    public RoleAuthorizeAttribute(string redirectUrl) : base() 
    { 
     this.redirectUrl = redirectUrl; 
    } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsAuthenticated) 
     { 
      string authUrl = this.redirectUrl; //passed from attribute 

      //if null, get it from config 
      if (String.IsNullOrEmpty(authUrl)) 
       authUrl = System.Web.Configuration.WebConfigurationManager.AppSettings["RolesAuthRedirectUrl"]; 

      if (!String.IsNullOrEmpty(authUrl)) 
       filterContext.HttpContext.Response.Redirect(authUrl); 
     } 

     //else do normal process 
     base.HandleUnauthorizedRequest(filterContext); 
    } 
} 

Wykorzystanie

[RoleAuthorize(Roles = "Admin, Editor")] 
public class AccountController : Controller 
{ 

} 

I upewnij się dodać swój wpis AppSettings w config

<appSettings> 
    <add key="RolesAuthRedirectUrl" value="http://mysite/myauthorizedpage" /> 
</appSettings> 
Powiązane problemy