9

我正在使用 Visual Studio 2011 beta 开发一个新的 asp.net mvc4 项目,并试图了解整个安全问题。它是一个内部 Intranet 应用程序,最初将使用单点登录,因此(还)不会提示用户输入 Windows ID/密码。该公司有一个自定义应用程序,用于存储不同应用程序的角色,并可通过存储过程调用获得。它将获取用户的登录 ID 并返回某种包含角色的集合,例如“MyApp.Data”、“MyApp.User”、“MyApp.Admin”。所以这被称为 - 这是一个自定义成员资格提供程序,自定义角色提供者还是别的什么?

我一直在阅读有关授权、身份验证、成员资格、角色等的所有细节,目前我看不到树木的木材。我读过现有的 ASP.NET 安全对象已经过试验和测试,除非有非常复杂的要求,否则内置的就足够了,所以我很乐意使用已经存在的东西。

因此,如果用户已经登录到网络,这意味着他们已经过身份验证 - 对吗?如果是这样,那么我只需要实现授权。是否需要用 Authorize 属性来装饰每个 Controller 或 Action?如果是这样,如果我从自定义角色存储应用程序中检索角色,[Authorize(Roles = "ABC")] 的“ABC”部分如何设置?

我阅读了几篇文章和博客文章,包括 Jon Galloway 的这篇文章,但最后我迷路了:

以正确的方式自定义身份验证和授权

这么多问题......如果有人知道所有这些如何联系在一起的良好高级描述,那么我会全神贯注:)

4

3 回答 3

8

好的,如果没有一个答案可以对所有这些是如何联系在一起的,我想我会草草写下我的发现:

所以在 Global.asax 我要补充:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new System.Web.Mvc.AuthorizeAttribute()); //new
}
  • 一旦用户通过身份验证,我就需要处理授权。该公司有一个现有的全局数据存储,用于存储我没有更新访问权限的角色,只有读取访问权限,因此我可以通过存储的 proc 调用检索给定用户的角色。提出请求后,帮助台创建角色可能需要几天到几周的时间,因此最初将创建 2 个标准角色,用户和管理员,后续角色将存储在我们的应用程序数据库中.

  • 除了这两个标准角色之外,还需要后续角色,例如超级用户等。这些角色将根据业务规则等具有各种权限,并且需要存储在我们的应用程序数据库中。因此,对于这种情况,我需要创建一个自定义角色提供程序,将适当的 asp.net 角色表添加到我的应用程序数据库中,并将其插入 web.config。这是一个名为“使用角色管理授权”的 ms 页面,我从中挑选了一些内容:

    http://msdn.microsoft.com/en-us/library/9ab2fxh0.aspx

  • 到目前为止,我所阅读的自定义角色提供程序所需的唯一表是 Roles 和 UsersInRoles。

    创建表角色(角色名称文本(255)非空,应用程序名称文本(255)非空,约束 PKRoles 主键(角色名称,应用程序名称))

    CREATE TABLE UsersInRoles(用户名文本(255)非空,角色名文本(255)非空,应用程序名文本(255)非空,约束PKUsersInRoles主键(用户名,角色名,应用程序名))

  • 设置完所有这些后,我需要弄清楚如何将全局数据存储中的 2 个标准角色(用户和管理员)与存储在我的应用程序数据库中的自定义角色合并,以及是否可以使用(例如)[Authorize(Roles= “管理员,超级用户”)] 在控制器/操作上,或者如果我需要继承 AuthoriseAttribute 并做一些更聪明的事情。

  • 我刚刚意识到,当我使用 AD 进行身份验证时,我需要一种添加/注入当前用户所属角色集合的方法。因此,尽管我不需要任何自定义成员资格提供程序功能,但我仍然必须与 httpContext.User 交互以更新其 Roles 集合。

于 2012-05-28T18:37:47.270 回答
7

如果您的身份验证已经由 Windows 处理(我猜是通过 Active Directory),那么您正在寻找的是一种将角色与用户匹配的授权机制。您拥有的一种选择是将用户角色成功加载到当前会话中。然后创建一个自定义授权属性,该属性将检查当前会话是否具有您正在使用的必要角色

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited=true, AllowMultiple=true)]
public class CustomAuthorizationAttribute : AuthorizeAttribute
{
   protected override bool AuthorizeCore(HttpContextBase httpContext)
   {         
      IPrincipal user = httpContext.User;
      if (!user.Identity.IsAuthenticated)
      {
          return false;
      }

     //check your users against a database and return true or false
      return base.AuthorizeCore(httpContext);
   }
}

然后你可以像这样使用属性

[CustomAuthorization]
public ActionResult SomeAction()
{
   return View();
}

更新

AuthorizeCore 是用于检查是否应允许此用户访问相应的操作方法的方法。在此方法中,您可以根据您的数据库或存储角色的位置检查 httpContext.User.Identity.Name 属性。如果您通过 Active Directory 使用 Windows 身份验证,则 HttpContext.User.Identity 应该是WindowsIdentity的一个实例

于 2012-05-25T02:22:55.353 回答
1

与 RoleProvider 一起更新的 RolePrincipal 应该是获取与经过身份验证的用户关联的角色列表所需的全部内容。请记住,RolePrincipal 已经包含正确的 WindowsIdentity。

您不需要自定义 Authorize 属性。RolePrincipal/RoleProvider 将获取所需的角色并使用标准的 Authorize 属性。

看起来有点奇怪的是,您希望拥有应用程序特有的角色,但您说您还想要与来自单独公司商店的 Windows 用户相关联的角色。正如你所说,你想合并它们。这对我来说似乎不正确。您想在公司级别为您的应用程序管理角色,或者您想在本地级别管理它们。一般来说,你不会两者都做。

但是,如果这确实是您想要做的,那么您的 RoleProvider 听起来好像需要进行服务(例如 WCF)调用或 AD 调用以获取更多信息。也许windows用户所属的“组”的名称可以作为“角色”。然后,您将只过滤掉您的应用程序关心的那些组,并与您在本地角色数据库中找到的角色相结合。

收集完所有信息后,请确保指示 roleManager 将角色信息存储在 cookie 中。用户提出的每一个请求都经历了那个喧嚣是没有意义的。

于 2012-11-19T15:23:58.170 回答