Вы можете использовать пользовательский атрибут авторизации и сохранять роли в части пользовательских данных куки-файла аутентификации. Например, внутри вашего метода LogOn, проверив учетные данные, вы можете получить роли для данного пользователя из вашей базы данных и сохранить их в пользовательских данных:
// TODO: fetch roles from your database based on the username
var roles = "Admin|SomeRole";
var ticket = new FormsAuthenticationTicket(
1,
username,
DateTime.Now,
DateTime.Now.AddMilliseconds(FormsAuthentication.Timeout.TotalMilliseconds),
false,
roles
);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
{
Domain = FormsAuthentication.CookieDomain,
HttpOnly = true,
Secure = FormsAuthentication.RequireSSL,
};
// Emit the authentication cookie which in addition to the username will
// contain the roles in the user data part
Response.AppendCookie(authCookie);
Затем вы можете написать собственный атрибут авторизации, который будет использоваться для чтения куки-файла аутентификации и извлечения информации о ролях:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext.User.Identity.IsAuthenticated)
{
var authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
var ticket = FormsAuthentication.Decrypt(authCookie.Value);
var identity = new GenericIdentity(httpContext.User.Identity.Name);
var roles = (ticket.UserData ?? string.Empty).Split('|');
httpContext.User = new GenericPrincipal(identity, roles);
}
}
return base.AuthorizeCore(httpContext);
}
}
Теперь осталось только украсить ваши контроллеры / действия этим новым атрибутом:
[MyAuthorize(Roles = "Admin")]
public ActionResult Foo()
{
...
}
UPDATE:
В соответствии с запросом в разделе комментариев, вот как можно переопределить метод HandleUnauthorizedRequest
в пользовательском атрибуте authorize, чтобы, если пользователь не авторизован для доступа к данному действию, он перенаправлялся на какое-то представление об ошибках вместо страницы входа в систему:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Shared/Unauthorized.cshtml"
};
}