W sytuacji gdy nie korzystamy z Membership, a chcemy kontrolować dostęp do akcji w kontrolerach przez role, możemy to osiągnąć przez stworzenie własnego filtru autoryzacji.
1) Utworzenie nowej klasy dziedziczącej po AuthorizeAttributeJest to prostszy sposób. Wystarczy nadpisać metodę AuthorizeCore, której parametrem wejściowym jest HttpContextBase. Klasa ta daje dostęp m.in. do:
- Session
- Request
- Response
W poniższym przykładzie w Session przechowywany jest obiekt WebCurrentUser, który zawiera m.in. informację o roli jaką posiada uwierzytelniony użytkownik. Przez kontruktor do filtru przekazywana jest lista akceptowanych ról, a w metodzie AuthorizeCore następuje porównanie.
public class CustomAuthorizeAttribute : AuthorizeAttribute { private string[] allowedRoles; public CustomAuthorizeAttribute(params string[] roles) { this.allowedRoles = roles; } protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext.Request.IsAuthenticated) { var user = (WebCurrentUser)httpContext.Session[WebCurrentUser.CURRENT_USER]; if (user != null) { return allowedRoles.Contains(user.Role.Name); } else return false; } else return false; } }2) Implementacja interfejsu IAuthorizationFilter
W tym przypadku należy stworzyć własną implementację obsługi autoryzacji implementując OnAuthorization. Należy samemu stworzyć właściwości Users/Roles (o ile są potrzebne).
public class CustomAuthorizeAttribute: FilterAttribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationContext filterContext) { if (!IsValid(filterContext)) { filterContext.Result = new HttpUnauthorizedResult(); } } private bool IsValid(AuthorizationContext filterContext) { //wlasna obsluga return true; } }Żądania ajax
Przekierowanie do strony logowania następuje dla wszystkich żądań - również dla wywołań ajax. Może to spowodować wyświetlenie strony logowania np. w oknie popup, iframe czy fragmencie strony. Aby tego uniknąć można wykorzystać również własny filtr autoryzacji.
Wystarczy nadpisać metodę HandleUnauthorizedRequest, której parametrem wejściowym jest AuthorizationContext. Dzięki temu można uzyskać dostęp do HttpContext i sprawdzić jakiego rodzaju jest żądanie. Jeśli ajax to można podmienić Result zwracając Json i w kodzie Javascript pokazać np. komunikat a po nim przekierować na stronę logowania.
protected override void HandleUnauthorizedRequest(AuthorizationContext context) { if (context.HttpContext.Request.IsAjaxRequest()) { UrlHelper url = new UrlHelper(context.RequestContext); context.Result = new JsonResult { Data = new { Error = "NotAuthorized", RedirectTo = url.Action("LogOn", "Profile") }, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } else { base.HandleUnauthorizedRequest(context); } }