Как я знаю, все действия внутри контроллера, украшенные атрибутом authorize, будут принимать по умолчанию одно и то же значение атрибута (если контроллер разрешает атрибут role = admin, например, автоматически все действия, которые не оформлены с любыми атрибутами будет взять ту же роль = администратора), но эта логика не работает в моем случаеПользовательский Авторизовать работает на уровне действия, но не на уровне контроллера
здесь мой заказ санкционировать детали
public class CustomAuthorize : AuthorizeAttribute
{
public string Url { get; set; }
public string Claims { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.User.Identity.IsAuthenticated)
{
return false;
}
else if (!string.IsNullOrWhiteSpace(Claims))
{
var claims = httpContext.GetOwinContext().Authentication.User.HasClaim(t => t.Type == "claim"
&& Claims.Split(',').Contains(t.Value));
if (!claims)
{
return false;
}
else
return true;
}
else if (!string.IsNullOrWhiteSpace(Roles))
{
var roles = httpContext.GetOwinContext().Authentication.User.HasClaim(t => t.Type == "role"
&& Roles.Split(',').Contains(t.Value));
if (!roles)
{
return false;
}
else
return true;
}
return base.AuthorizeCore(httpContext);
}
public bool IsAuthorized(string claim)
{
if (!string.IsNullOrEmpty(Claims))
return Claims.Split(',').Contains(claim);
return true;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!string.IsNullOrEmpty(Url))
filterContext.Result = new RedirectResult(Url);
else
base.HandleUnauthorizedRequest(filterContext);
}
}
вспомогательный метод для проверки подлинности
public static bool ActionIsAuthorized(this HtmlHelper helper, string actionName, string controllerName)
{
IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
ControllerBase controller = factory.CreateController(helper.ViewContext.RequestContext, controllerName) as ControllerBase;
var controllerContext = new ControllerContext(helper.ViewContext.RequestContext, controller);
var controllerDescriptor = new ReflectedControllerDescriptor(controller.GetType());
var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor);
foreach (var authAttribute in actionDescriptor
.GetFilterAttributes(true)
.Where(a => a is CustomAuthorize).Select(a => a as CustomAuthorize))
{
authAttribute.OnAuthorization(authContext);
if (authContext.Result != null)
return false;
}
return true;
}
и использование в представлении, как
@if(Html.ActionIsAuthorized("Index","Appointment", new {area="Employee"})){
@Html.ActionLink("Appointments","Index","Appointment",new {area = "Employee"})
}
Когда я использую приведенный выше код, как показано ниже, он не будет работать (ссылка назначение еще показано)
[CustomAuthorize(Claims="Add Appointment",Url="~/Employee/Home/Login")]
public class AppointmentController: BaseController
{
public ActionResult Index()
{
// code here
}
}
в то время как, если я использую его следующим образом, он работает
public class AppointmentController: BaseController
{
[CustomAuthorize(Claims="Add Appointment",Url="~/Employee/Home/Login")]
public ActionResult Index()
{
// code here
}
}
может кто-нибудь сказать мне, почему действие не принимает атрибут по умолчанию, когда я украшаю контроллер? или я что-то пропустил?
Что вы подразумеваете под «не работает». Вы имеете в виду, что код в CustomAttribute не выполняется по методу «Index», когда вы применяете атрибут на уровне класса? – granadaCoder
@granadaCoder запускается, но не читает значения пользовательских атрибутов (функция ActionIsAuthorized) – mah