使用 simplemembership 的新 MVC 4 Internet 模板中基于角色的身份验证

Posted

技术标签:

【中文标题】使用 simplemembership 的新 MVC 4 Internet 模板中基于角色的身份验证【英文标题】:Role based authentication in the new MVC 4 Internet template using simplemembership 【发布时间】:2012-08-28 17:51:31 【问题描述】:

我喜欢 MVC 4 互联网模板中的新 simplemembership 功能,其中包含指向 VS 2012 RTM 中外部登录的 OAuth 的链接。大多数情况下,身份验证功能都在工作。但是,即使在此花费了 8 多个小时后,我也无法实施基于角色的授权来在我的控制器上工作。事实证明,SimpleMembership 绝非简单。

我已经搜索了 ***,谷歌搜索并阅读了 John Galloway 的最新消息,尝试了很多建议,但仍然无法解决这个问题。这一切都始于出现 Sql 连接错误,并且无法弄清楚为什么连接字符串和其他一切都很好。花了好几个小时才弄清楚是 Roles 类导致了问题。

控制器上的 [Authorize] 属性与以前一样用于基本身份验证。但是每当我尝试使用角色时,它都会出现 sql 连接错误(因为它会恢复为旧的 DefaultRolesProvider,它试图连接到默认的 SqlExpress aspnetdb 文件并失败)。所以像:

[Authorize(Roles="admin")]

不起作用。如果我回到旧的 asp.net 会员提供程序,它会起作用,但是我会丢失简单的数据库表、基于令牌的确认和恢复、更安全的密码哈希以及更重要的是通过 OAuth 进行的外部登录。

在代码和 razor 视图中唯一起作用的是

User.IsInRole("admin")

这对于菜单项等来说是可以的,但在控制器中的每个动作中实现起来非常麻烦(而且我不喜欢它一次只测试一个角色)。

我将非常感谢任何解决此问题的指导。

【问题讨论】:

【参考方案1】:

找到一个答案here by Mehdi Golchin 似乎可以解决:

[Authorize(Roles="admin,editor,publisher")]

如果我也将它添加到家庭控制器:

 [InitializeSimpleMembership]

因为这个属性在 Accounts 控制器上,SimpleMembership 数据库只有在第一次使用帐户控制器(如登录/注册)后才会初始化。即使当前用户从 cookie 登录,数据库也不会初始化,因此会引发错误。一种解决方案是将此属性放在主控制器上,当我启动我的网站时会调用它。但是,它需要放置在每个控制器上,因为我检查角色并根据角色显示不同的菜单项。

这是一个糟糕的设计,因为数据库应该在 App_Start 上初始化,而不是在第一次使用时初始化。

我确实尝试过

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);

Global.asaxApplication_Start() 中,它使用User.IsInRole("admin") 处理菜单项中的角色检查,但随后在具有[Authorize(Roles="admin")] 属性的任何控制器中抛出错误,即使应用了附加属性[InitializeSimpleMembership]

因此,现在的解决方案是将 `[InitializeSimpleMembership] 放在所有控制器上,因为用户最初可能会使用外部链接登陆任何页面。

它仍然不知道如何初始化 SimpleRolesProvider 类来做更多的角色管理,而不仅仅是User.IsInRole()

这些东西在 webmatrix 网页站点中效果更好,显然 MVC 端口不完整。它与默认的 asp.net 会员提供程序发生冲突并混淆。

编辑 好的,我不认为 [InitializeSimpleMembership] 过滤器可以通过将此行放在 App_Start 文件夹中的 FilterConfig.cs 中来全局应用:

filters.Add(new InitializeSimpleMembershipAttribute());

这就解决了这个问题。现在需要一个 SimpleRolesProvider 初始化的解决方案,否则我将不得不编写自己的角色提供程序。

更新:

这个post by Scott Allen解决了我所有的问题。

通过将其包含在 web.config 中:

<roleManager enabled="true" defaultProvider="simple">
  <providers>
    <clear/>
    <add name="simple" type="WebMatrix.WebData.SimpleRoleProvider,               WebMatrix.WebData"/>
  </providers>      
</roleManager>
<membership defaultProvider="simple">
  <providers>
    <clear/>
    <add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider,                          WebMatrix.WebData"/>
  </providers>
</membership>

Roles 和 Membership 类的所有方法都可用,可以在代码中初始化如下:

var roles = (SimpleRoleProvider) Roles.Provider;
var membership = (SimpleMembershipProvider) Membership.Provider;

【讨论】:

不得不提的是,上面的配置内容应该在 部分。 感谢 Ahmed,你让我免于头痛! 谢谢先生。你不知道这对我有多大帮助。 对于基于角色的身份验证,例如使用[Authorize(Roles="Admin")] 时,如果用户已登录但未初始化WebSecurity,您将收到错误,因为授权过滤器首先运行。将InitializeSimpleMembershipAttribute 设为IAuthorizationFilter、see post【参考方案2】:

当我将我的 Web 应用程序从 VS2010/MVC3 移动到 VS2012/MVC4 时遇到了同样的问题。

并且无法让 [InitializeSimpleMembership] 工作。

发现将其添加到您的 web.config 可以解决问题:

  <appSettings>
    <add key="enableSimpleMembership" value="false" />
  </appSettings>

一切都和以前一样正常。

【讨论】:

以上是关于使用 simplemembership 的新 MVC 4 Internet 模板中基于角色的身份验证的主要内容,如果未能解决你的问题,请参考以下文章

实体框架代码优先问题(SimpleMembership UserProfile 表)

MVC 密码重置邮件 NO SIMPLEMEMBERSHIP

如何将我自己的数据库与 SimpleMembership 和 WebSecurity 一起使用?啥是 MVC4 安全性?

SimpleMembership 会在 MVC3 DB 优先应用程序中工作吗?

Simplemembership ASPXAUTH cookie 在两个单独的 Web 项目上进行验证

WebAPI + SimpleMembership + WebSecurity - 永远无法进行身份验证?