Авторизация и аутентификация в приложении MVC - PullRequest
3 голосов
/ 09 августа 2011

Авторизация и аутентификация в приложении MVC

У меня есть внутреннее веб-приложение, разработанное на C # с использованием MVC 2. Я хочу использовать роли / группы AD для авторизации. Таким образом у меня есть 3 группы доступа Admin, Basic, Readonly. Доступ к приложению будет контролироваться через эти группы.

Теперь, когда я нажимаю на действие / страницу моего приложения MVC, требования:

1) Проверить уровень доступа (находится в группе Admin, Basic или Readonly)

2) Если в группе - обслуживать страницы. Если нет - отправьте страницу 401 Несанкционированный.

Я, вероятно, путаю себя с концепцией авторизации / аутентификации, но так она настроена до сих пор (из ответов, Google и моих собственных усилий, вытекающих из этого вопроса :

public static class AuthorizationModule
    {
        public static bool Authorize(HttpContext httpContext, string roles)
        {
            ...
            //Check Configuration.AppSettings for the roles to check

            //using httpContext.User check .IsInRole for each role and return true if they are

            ...

            //other wise throw new HttpException(401,.....)
        }

        ...
    }

    public class AuthorizeByConfigurationAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //Essentially at the moment this is pretty much the same as AuthorizationModule.Authorize(HttpContext httpContext, string roles)
        }

    }

    //This code from http://paulallen.com.jm/blog/aspnet-mvc-redirect-unauthorized-access-page-401-page
    public class RequiresAuthenticationAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                filterContext.Result = new ViewResult {ViewName = "AccessDenied"};
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }
    }

Проблемы с этим заключаются в том, что мне, кажется, теперь нужно дважды украсить свои методы действия, ала:

[AuthorizeByConfiguration(Roles = "Admin, Basic, Readonly")]
        [RequiresAuthentication(Roles = "Admin, Basic, Readonly")]
        public ActionResult Index(string msg)
        {
            ...
        }

И следующая проблема в том, что, похоже, у меня есть три отдельных метода, пытающихся сделать то же самое. Я переопределяю методы, основанные на советах, и не совсем уверен, как они должны были работать изначально. Как я могу реализовать свои требования?

edit: так как это приложение IntrAnet, все пользователи, которые входят в систему с использованием своих сетевых учетных записей, смогут получить доступ к этому приложению. Мне нужно ограничить доступ, чтобы только те, кто принадлежит к определенным группам безопасности Active Directory, могли получить доступ к этому приложению

1 Ответ

2 голосов
/ 09 августа 2011

Я обернул все методы, относящиеся к аутентификации, интерфейсом IAuthorization.

Вот пример настраиваемого атрибута, который вам понадобится для добавления свойства Roles и вашей собственной реализации.

Атрибут вызывает сам фильтр по соображениям тестируемости.

public class SomeAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var filter = new SomeAuthorizeFilter(DependencyLookup.Resolve<IAuthorization>());
        filter.OnAuthorization(filterContext);
    }
}

public class SomeAuthorizeFilter : IAuthorizationFilter
{
    private readonly IAuthorization _authorization;

    public SomeAuthorizeFilter(IAuthorization authorization)
    {
        _authorization = authorization;
    }

    protected virtual ActionResult ResultWhenNotAuthenticated(AuthorizationContext filterContext)
    {
        //snip..

        //default
        RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary
                                                            {
                                                                {"action", "Index"},
                                                                {"controller", "Home"}
                                                            };
        return new RedirectToRouteResult(redirectTargetDictionary);
    }

    #region IAuthorizationFilter Members

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!_authorization.GetCurrentUserIdentity().IsAuthenticated)
        {
            filterContext.Result = ResultWhenNotAuthenticated(filterContext);
        }
    }

    #endregion
}
...