53

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

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

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

[Authorize(Roles="admin")]

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

在代码和剃刀视图中唯一有效的是

User.IsInRole("admin")

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

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

4

2 回答 2

69

在这里找到了 Mehdi Golchin的答案,似乎可以解决:

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

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

 [InitializeSimpleMembership]

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

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

我确实尝试过

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

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

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

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

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

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

filters.Add(new InitializeSimpleMembershipAttribute());

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

更新:

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;
于 2012-09-04T16:12:11.727 回答
6

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

并且无法让 [InitializeSimpleMembership] 工作。

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

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

一切都像以前一样正常。

于 2013-02-28T15:30:39.663 回答