представление двух разных экранов входа в систему на основе ролей

Я пытался выяснить, можно ли представить два разных экрана входа в систему на основе роли авторизации. Требование простое. У меня есть две роли: "admin" и "public". Во всех методах действий моих приложений для этих двух ролей отмечены атрибуты «Авторизовать».

Теперь в требованиях моего приложения указаны разные экраны входа для «admin» и «public». Экран входа «admin» защищен дополнительным защитным кодом, который не требуется для экрана входа «public». Я искал какой-то способ узнать, кто пытается войти в систему, на основе вызванного метода Action. Если вызываемый метод действия украшен Authorize[Roles="admin"], то я бы представил экран входа администратора, тогда как если вызываемый метод действия применяется Authorize[Roles="public"], тогда мне нужно представить общедоступный экран входа.

Если экран входа вызывается напрямую, то по умолчанию будет представлен общедоступный экран входа.

Это может показаться немного странным, но это сценарий, для которого я пытаюсь найти решение.


person Jatin    schedule 14.11.2011    source источник
comment
Разве это не парадокс — как вы узнаете роль пользователя, пока он не войдет в систему, и как вы можете показать ему экран входа в систему, пока вы не узнаете его роль?   -  person Widor    schedule 14.11.2011
comment
@Widor, я думаю, что ему нужно то, что если не прошедший проверку подлинности пользователь пытается выполнить действие контроллера, для которого требуется роль администратора, его нужно перенаправить на другой экран входа в систему, чем если бы он пытался выполнить действие контроллера, требующее какая-то другая роль.   -  person Darin Dimitrov    schedule 14.11.2011
comment
@Nirvan А, я вижу, все в порядке.   -  person Widor    schedule 14.11.2011


Ответы (1)


Вы можете написать собственный атрибут авторизации, который будет перенаправлять на правильное действие logon:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        var roles = Roles.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        if (roles.Contains("admin", StringComparer.OrdinalIgnoreCase))
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
            {
                controller = "account",
                action = "adminlogon",
                returnUrl = filterContext.HttpContext.Request.RawUrl
            }));
        }
        else
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
            {
                controller = "account",
                action = "logon",
                returnUrl = filterContext.HttpContext.Request.RawUrl
            }));
        }
    }
}

а затем украсьте им свои контроллеры/экшены:

[MyAuthorize(Roles = "admin")]
public ActionResult Foo()
{
    return View();
}

[MyAuthorize(Roles = "normaluser")]
public ActionResult Bar()
{
    return View();
}

Теперь, если неаутентифицированный пользователь попытается выполнить действие Foo, он будет перенаправлен на действие /account/adminlogon, а если он попытается нажать действие Bar, он будет перенаправлен на действие /account/logon. В обоих случаях текущий URL-адрес будет передан как параметр returnUrl, чтобы после успешного входа пользователь мог попасть на страницу, которую он изначально пытался просмотреть.

person Darin Dimitrov    schedule 14.11.2011
comment
Дарин, Ваше решение работает хорошо. Атрибут MyAuthorize обрабатывает перенаправление на разные экраны входа. Большое спасибо. - person Jatin; 14.11.2011