2009-09-17 16 views
12

Używam ActionFilterAttribute do wykonania niestandardowej logiki uwierzytelniania. Atrybut będzie używany tylko w pochodnej klasie kontrolera, która zawiera moją logikę uwierzytelniania.ActionFilterAttribute - zastosowanie do działań określonego kontrolera typu

Oto mój Controller, pochodzące z mojej klasy niestandardowej kontrolera, a atrybut próbki:

public class MyController : CustomControllerBase 
{ 

    [CustomAuthorize(UserType = UserTypes.Admin)] 
    public ActionResult DoSomethingSecure() 
    { 
     return View(); 
    } 

} 

Oto przykład mojego ActionFilterAttribute:

public class CustomAuthorizeAttribute : ActionFilterAttribute 
{ 
    public MyUserTypes UserType { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     myUser user = ((CustomControllerBase)filterContext.Controller).User; 

     if(!user.isAuthenticated) 
     { 
     filterContext.RequestContext.HttpContext.Response.StatusCode = 401; 
     } 
    } 
} 

działa świetnie.

Oto pytanie: Czy mogę wymagać, aby ten atrybut był WYŁĄCZNIE używany w działaniach w moim niestandardowym typie kontrolera?

+1

Twój atrybut jest uszkodzony, ponieważ nie dziedziczy z AuthroizeAttribute i nie można zagwarantować, że będzie działał, gdy czynność zostanie zapisana w pamięci podręcznej. Zobacz http://blogs.teamb.com/craigstuntz/2009/09/09/38390/ dla rozwiązań, które działają z buforowaniem. –

+0

Dlaczego wynik działania byłby buforowany? –

+0

Zostanie zbuforowany, ponieważ ktoś powiedział, że ma być buforowany. Wyobraź sobie, że ktoś umieszcza atrybut Cache na klasie nadrzędnej, nie zauważając złamanego atrybutu podtypu. O wiele lepiej jest używać atrybutu, który nie jest zasadniczo niezgodny z buforowaniem ASP.NET/MVC. Zobacz link powyżej, aby uzyskać opcje. –

Odpowiedz

14

Możesz umieścić ActionFilter na samej klasie. Wszystkie akcje w klasie zrealizują ActionFilter.

[CustomAuthorize] 
public class AuthorizedControllerBase : CustomControllerBase 
{ 
} 

public class OpenAccessControllerBase : CustomControllerBase 
{ 
} 

public class MyRealController : AuthorizedControllerBase 
{ 
    // GET: /myrealcontroller/index 
    public ActionResult Index() 
    { 
     return View(); 
    } 
} 
+0

Właśnie wybieram trasę definiowania ActionFilter w klasie (więc nie jest dostępna na innych klasach). Dobrze jest wiedzieć, że atrybut można zdefiniować dla wszystkich akcji ActionResults w kontrolerze. –

7

Na podstawie komentarzy i ograniczeń mojego systemu zastosowałem podejście hybrydowe. Zasadniczo, jeśli żądanie przychodzi przez buforowaną trasę lub "Użytkownik" nie jest ustawiony z jakiegokolwiek powodu, uwierzytelnianie nie powiedzie się we właściwy sposób.

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    private MyUser User { get; set; } 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
    //Lazy loads the user in the controller. 
    User = ((MyControllerBase)filterContext.Controller).User; 

    base.OnAuthorization(filterContext); 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
    bool isAuthorized = false; 
    string retLink = httpContext.Request.Url.AbsolutePath; 

    if(User != null) 
    { 
     isAuthorized = User.IsValidated; 
    } 

    if (!isAuthorized) 
    { 
     //If the current request is coming in via an AJAX call, 
     //simply return a basic 401 status code, otherwise, 
     //redirect to the login page. 
     if (httpContext.Request.IsAjaxRequest()) 
     { 
     httpContext.Response.StatusCode = 401; 
     } 
     else 
     { 
     httpContext.Response.Redirect("/login?retlink=" + retLink); 
     } 
    } 

    return isAuthorized; 
    } 
} 
+0

Jeśli przekierowujesz w przypadku "isAuthorized = false", dlaczego po prostu nie zwrócisz wartości true na końcu? – Alex

+0

W przypadku przepływu IsAjaxRequest użytkownik nie jest przekierowywany, więc metoda musi jeszcze powrócić. –

+0

+1 za używanie AuthorizeAttribute zamiast ActionFilterAttribute. Rozwiązuje problem polegający na tym, że akcja kontrolera mająca atrybut CustomAuthotize jest wykonywana, nawet jeśli nie jesteśmy zalogowani, co może powodować inne problemy. –

Powiązane problemy