使用 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.asax
Application_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;
【讨论】:
不得不提的是,上面的配置内容应该在[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 优先应用程序中工作吗?