【问题标题】:Authorization and authentication in MVC applicationMVC 应用程序中的授权和认证
【发布时间】:2011-08-09 03:57:07
【问题描述】:

MVC 应用中的授权和认证

我有一个使用 MVC 2 用 C# 开发的内部 Web 应用程序。我想使用 AD 角色/组进行授权。因此,我有 3 个访问组 Admin、Basic、Readonly。对应用程序的访问将通过这些组进行控制。

现在,当我点击我的 MVC 应用的操作/页面时,要求是:

1) 检查访问级别(在 Admin、Basic 或 Readonly 组中)

2) 如果在一个组中 - 提供页面。 如果没有 - 提供 401 Unauthorized 页面。

我可能对授权/身份验证的概念感到困惑,但这就是到目前为止的设置方式(来自答案、谷歌和我自己的努力来自question

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)
        {
            ...
        }

下一个问题是,我似乎有三种不同的方法都试图做同样的事情。我正在根据建议覆盖方法,并不完全确定它们最初是如何工作的。我该如何实现我的要求?

编辑:由于这是一个 IntrAnet 应用程序,所有使用其网络帐户登录的用户都可以访问此应用程序。我需要限制访问,以便只有属于某些 Active Directory 安全组的人才能访问此应用

【问题讨论】:

  • 如果你把你的属性放在类声明中,那么它将适用于所有的动作(方法)。
  • 为什么不将这两个过滤器结合起来,忘记“原始实现”并编写您希望它现在如何工作的方式?
  • @CRice 没问题。我不确定如何“忘记原始实现”。因为我正在覆盖现有的行为。例如。如果我想将其全部放入AuthorizeCore - 我不能,因为我没有AuthorizationContext filterContext,而且我无法在其中返回我的AccessDenied 视图,因为它返回bool。我是否编写了“一个主要方法”,然后从每个事件中调用它?你能提供相同的代码/存根吗?谢谢

标签: c# asp.net-mvc asp.net-mvc-2 authentication authorization


【解决方案1】:

我已经用接口 IAuthorization 封装了所有关于 auth 的方法。

这是一个示例自定义属性,您需要添加 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
}

【讨论】:

  • 好吧,我不知道你在 public override void OnAuthorization(AuthorizationContext filterContext)DependencyLookup 中所做的事情在当前上下文中不存在。还有行 if (!_authorization.GetCurrentUserIdentity().IsAuthenticated) - Microsoft.Data.Schema.ScriptDom.Sql.IAuthorization 不包含 GetCurrentUserIdentity 的定义。我现在如何装饰我的控制器动作/方法?你到底是如何获得这些方法如何工作的如此具体的知识——这样你才能理解如何重写/覆盖它们!?!??
  • 依赖查找只是对我的服务定位器的调用,以获取 IAuthorization 实例(我编写的类 Authorization 的新实例)。所以这可以写成“new Authorization()”。如果您阅读了我提到的答案的第一行,我创建了这个界面,这也是您没有 IAuthorization 的原因。这不是一个复制和粘贴工作 - 只是一个示例供您用来创建您的实现。
  • 我基本上和上面的骨架呆在一起。我把所有东西都带入了AuthorizeByConfigurationAttribute,然后身份验证生命周期实际上开始按照它应该的方式工作,并且一切都开始协同工作。 (AuthorizeCore 将传递给HandleUnauthorizedRequest,具体取决于)。我DID 使用了您的解决方案,但无法真正理解它(与我的骨架相比)并且无法得到一些可以编译的东西 - 并且不得不放弃。不幸的是,我仍然不知道IAuthorizationFilter 是关于什么的。我想我需要研究接口。
猜你喜欢
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 1970-01-01
  • 2013-10-07
  • 2015-03-05
  • 2018-11-27
  • 1970-01-01
相关资源
最近更新 更多