Ответ 1
Кажется, ASP.NET MVC 4 "исправил" это, добавив атрибут AllowAnonymous.
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
// ...
}
// ...
}
У меня есть базовый класс контроллера MVC, на который я применил атрибут Authorize, так как я хочу, чтобы почти все контроллеры (и их действия) были авторизованы.
Однако мне нужно, чтобы контроллер и действие другого контроллера были несанкционированы. Я хотел бы украсить их с помощью [Authorize(false)]
или что-то, но это не доступно.
Любые идеи?
Кажется, ASP.NET MVC 4 "исправил" это, добавив атрибут AllowAnonymous.
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
public ActionResult Login()
{
// ...
}
// ...
}
Изменить: поскольку ASP.NET MVC 4 лучше всего использовать встроенный атрибут AllowAnonymous.
Ниже приведен ответ на более ранние версии ASP.NET MVC
Вы можете создать собственный атрибут авторизации, наследующий от стандартного AuthorizeAttribute, с необязательным параметром bool, чтобы указать, требуется ли авторизация или нет.
public class OptionalAuthorizeAttribute : AuthorizeAttribute
{
private readonly bool _authorize;
public OptionalAuthorizeAttribute()
{
_authorize = true;
}
public OptionalAuthorizeAttribute(bool authorize)
{
_authorize = authorize;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if(!_authorize)
return true;
return base.AuthorizeCore(httpContext);
}
}
Затем вы можете украсить ваш базовый контроллер этим атрибутом:
[OptionalAuthorize]
public class ControllerBase : Controller
{
}
и для любых контроллеров вы не хотите, чтобы авторизация просто использовала переопределение с помощью "false" - например,
[OptionalAuthorize(false)]
public class TestController : ControllerBase
{
public ActionResult Index()
{
return View();
}
}
Мое личное занятие - это разделить контроллер. Просто создайте другой контроллер. Для действий вам не нужна аутентификация.
Или вы могли бы:
BaseController
не требует аутентификации - здесь у вас есть все ваши "базовые вещи":).
BaseAuthController : BaseController
все действия здесь требуют аутентификации.
Таким образом, вы можете иметь аутентификацию, когда хотите, просто путем получения определенного класса.
Если вы просто хотите, чтобы одно действие было неавторизованным на другом авторизованном контроллере, вы можете сделать что-то вроде этого:
public class RequiresAuthorizationAttribute : ActionFilterAttribute
{
private readonly bool _authorize;
public RequiresAuthorizationAttribute()
{
_authorize = true;
}
public RequiresAuthorizationAttribute(bool authorize)
{
_authorize = authorize;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var overridingAttributes = filterContext.ActionDescriptor.GetCustomAttributes(typeof (RequiresAuthorizationAttribute), false);
if (overridingAttributes.Length > 0 && overridingAttributes[0] as RequiresAuthorizationAttribute != null && !((RequiresAuthorizationAttribute)overridingAttributes[0])._authorize)
return;
if (_authorize)
{
//redirect if not authenticated
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//use the current url for the redirect
var redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;
//send them off to the login page
//var redirectUrl = string.Format("?RedirectUrl={0}", redirectOnSuccess);
var loginUrl = LinkBuilder.BuildUrlFromExpression<HomeController>(filterContext.RequestContext, RouteTable.Routes,
x => x.Login(redirectOnSuccess));
filterContext.HttpContext.Response.Redirect(loginUrl, true);
}
}
}
}