Почему функция onAuthorization выполняется перед аутентификацией?
Я пытаюсь выполнить специальную авторизацию, поэтому я создал контроллер, переопределяющий метод OnAuthorization
. Я также применил атрибут Authorize
к этому контроллеру.
Вопрос в том, почему метод OnAuthorization
называется ПЕРЕД началом процесса аутентификации основных форм?
Я хотел бы авторизовать пользователя после его аутентификации.
Я что-то пропустил?
Вот код:
[Authorize]
public class AuthorizationController : Controller
{
protected override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
List<string> allowedControllers = new List<string>() { "SecurityController" };
List<string> allowedActions = new List<string>() { "Index" };
string controllerName = filterContext.Controller.GetType().Name;
string actionName = filterContext.ActionDescriptor.ActionName;
if (!allowedControllers.Contains(controllerName)
|| !allowedActions.Contains(actionName))
{
filterContext.Result = View("UnauthorizedAccess");
}
}
}
Контроллер, с которым я тестировал, выглядит примерно так:
public class SecurityController : AuthorizationController
{
public ActionResult Index()
{
return View();
}
public ActionResult AnotherIndex()
{
return View();
}
}
Ответы
Ответ 1
Одна из первых вещей, которую выполняет AuthorizeAttribute
, - это проверить, проверяется ли пользователь. Если это не так, тогда выдается перенаправление на страницу входа.
AuthorizeAttribute
в основном завершает проверку подлинности с помощью части авторизации:
protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
if (httpContext == null) {
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated) {
return false;
}
Когда вы используете AuthorizeAttribute без ролей/пользователей, как в своем примере ([Авторизовать]), в основном это проверка, чтобы убедиться, что пользователь аутентифицирован в этом случае.
Я бы, вероятно, изменил ваш код, чтобы переопределить AuthorizeAttribute, а не делать этот код в вашем контроллере. Вы можете сделать следующее:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
filterContext.Result = CreateResult(filterContext);
}
protected ActionResult CreateResult(AuthorizationContext filterContext)
{
var controllerContext = new ControllerContext(filterContext.RequestContext, filterContext.Controller);
var controller = (string)filterContext.RouteData.Values["controller"];
var action = (string)filterContext.RouteData.Values["action"];
// any custom model here
var model = new UnauthorizedModel();
// custom logic to determine proper view here - i'm just hardcoding it
var viewName = "~/Views/Shared/Unauthorized.cshtml";
return new ViewResult
{
ViewName = viewName,
ViewData = new ViewDataDictionary<UnauthorizedModel>(model)
};
}
}
Ответ 2
Ниже приведен образец атрибута пользовательской авторизации.
public class AuthLogAttribute:AuthorizeAttribute
{
public string View { get; set; }
public AuthLogAttribute()
{
View = "AuthorizeFailed";
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
IsUserAuthorized(filterContext);
}
private void IsUserAuthorized(AuthorizationContext filterContext)
{
// If the Result returns null then the user is Authorized
if(filterContext.Result ==null)
return;
//If the user is Un-Authorized then Navigate to Auth Failed View
if(filterContext.HttpContext.User.Identity.IsAuthenticated)
{
var vr = new ViewResult();
vr.ViewName = View;
ViewDataDictionary dict = new ViewDataDictionary();
dict.Add("Message", "Sorry you are not Authorized to Perform this Action");
vr.ViewData = dict;
var result = vr;
filterContext.Result = vr;
}
}
}
Ваш контроллер будет выглядеть следующим образом:
[AuthLog(Roles ="Manager")]
public ActionResult Create()
{
var product = new Product();
return View(product);
}
Наконец, создайте новый общий вызов "Авторизация".
Ответ 3
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
bool flag = false;
string UserId;
string[] AssignedRights = null;
//Check if Http Context Contains User Name
if (HttpContext.Current.User.Identity.Name != null && HttpContext.Current.User.Identity.Name != string.Empty)
{
//Get User Id from HttpContext
UserId = HttpContext.Current.User.Identity.Name;
RoleRepository roleRepository = new RoleRepository();
AssignedRights = roleRepository.GetRolesByUser(Convert.ToInt32(UserId));
flag = IsUserAuthorized(filterContext, flag, AssignedRights);
if (flag == false)
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}