问题描述
我喜欢 MVC 4 Internet 模板中新的 simplemembership 功能,其中包含指向 OAuth 的链接,以便在 VS 2012 RTM 中进行外部登录.大多数情况下,身份验证功能都在工作.然而,即使在这上面花费了 8 多个小时,我也无法实现基于角色的授权来处理我的控制器.事实证明,SimpleMembership 并不简单.
I like the new simplemembership feature in MVC 4 internet template with links to OAuth for external logins in VS 2012 RTM. For the most part authentication feature are working. However even after spending over 8 hours on this I am unable to implement roles based authorization to work on my controllers. SimpleMembership is turning out to be anything but simple.
我搜索过stackoverflow,用谷歌搜索过并阅读了最新的John Galloway,尝试了很多建议,但仍然一直无法解决这个问题.这一切都始于获取 Sql 连接错误,并且无法弄清楚为什么连接字符串和其他一切都很好.花了好几个小时才弄清楚是 Roles 类导致了问题.
I have searched stackoverflow, googled and have read the latest by John Galloway, tried many suggestions and still have not been able to resovle this issue. It all started with getting Sql connection error and could not figure out why when the connection string and everything else was good. It took many hours to figure out the it is Roles class that is causing problem.
控制器上的 [Authorize] 属性像以前一样用于基本身份验证.但是每当我尝试使用角色时,它都会出现 sql 连接错误(因为它恢复到旧的 DefaultRolesProvider,它尝试连接到默认的 SqlExpress aspnetdb 文件并失败).所以就像:
The [Authorize] attribute on controllers works as before for basic authentication. But any time I try to use Roles it give sql connection error (because it reverts to the old DefaultRolesProvider which tries to connect to default SqlExpress aspnetdb file and fails). So something like:
[Authorize(Roles="admin")]
不起作用.如果我回到旧的 asp.net 成员资格提供商,它会起作用,但随后我丢失了简单的数据库表、基于令牌的确认和恢复、更安全的密码散列以及更重要的通过 OAuth 进行的外部登录.
does not work. It will work if I go back to the old asp.net membership providers, but then I lose the simple database tables, token bases confirmation and recovery, more secure password hashing and more importantly external logins via OAuth.
在代码和剃刀视图中唯一有效的是
The only thing that works inside code and razor views is
User.IsInRole("admin")
这对于菜单项等是可以的,但是在控制器中的每个 Action 内部实现非常麻烦(我不喜欢它一次只测试一个角色).
which is OK for menu items and such, but ver cumbersome to implement inside every single Action in controller (and I do not like that it only tests for single role at a time).
我将不胜感激任何解决此问题的指导.
I will greatly appreciate any guidance to resovle this issue.
推荐答案
找到答案 here byMehdi Golchin 似乎很照顾:
Found an answer here by Mehdi Golchin which seems to take care of:
[Authorize(Roles="admin,editor,publisher")]
如果我也将它添加到家庭控制器:
If I also add this to the home controller:
[InitializeSimpleMembership]
因为这个属性在 Accounts 控制器上,所以 SimpleMembership 数据库只有在第一次使用账户控制器(如登录/注册)后才会被初始化.即使当前用户从 cookie 登录,数据库也不会初始化,因此会引发错误.一种解决方案是将此属性放在我启动网站时调用的家庭控制器上.但是,那么它需要放在每个控制器上,因为我检查角色并根据角色显示不同的菜单项.
Because this attribute is on the Accounts controller, SimpleMembership database gets initialize only after the first use of the accounts controller like login/register. Even when the current user gets logged in from the cookie, the database is not initialized and so it throws an error. One solution is to put this attribute on the home controller which gets called when I launch my Website. But, then it needs to be placed on every controller because I check roles and display different menu items based on role.
这是一个糟糕的设计,因为数据库应该在 App_Start 上初始化,而不是在第一次使用时.
This is poor design as the database should be initialized on the App_Start and not when first used.
我确实尝试过
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
在 Global.asax
Application_Start()
中,它使用 User.IsInRole("admin")
负责菜单项中的角色检查code>,但随后在任何具有 [Authorize(Roles="admin")]
属性的控制器中抛出错误,即使应用了附加属性 [InitializeSimpleMembership]
.
in the Global.asax
Application_Start()
, and it takes care of role checking in menu items using User.IsInRole("admin")
, but then throw error in any controller with [Authorize(Roles="admin")]
attribute, even with additional attribute [InitializeSimpleMembership]
is applied.
所以现在的解决方案是在所有控制器上放置`[InitializeSimpleMembership],因为用户最初可以使用外部链接登陆任何页面.
So right now the solution is to put `[InitializeSimpleMembership] on all controllers as a user may initially land on any page using external links.
它仍然不知道如何初始化 SimpleRolesProvider 类来完成更多的角色管理,而不仅仅是 User.IsInRole()
.
It still can't figure how to initialize the SimpleRolesProvider class to do more of the role management instead of just User.IsInRole()
.
这些东西在 webmatrix 网页站点中做得更好,显然 MVC 的端口不完整.它与默认的 asp.net 成员资格提供程序冲突并混淆.
These things do work better in the webmatrix webpages site and obviously the port ot MVC is not complete. It conflicts and gets confused with the default asp.net membership providers.
编辑好吧,我没想到 [InitializeSimpleMembership]
过滤器可以通过将此行放在 App_Start 文件夹中的 FilterConfig.cs
中来全局应用:
EDITOK I was not thinking [InitializeSimpleMembership]
filter could be applied globally by putting this line in the FilterConfig.cs
in the App_Start folder:
filters.Add(new InitializeSimpleMembershipAttribute());
这就解决了这个问题.现在需要 SimpleRolesProvider 初始化的解决方案,否则我将不得不编写自己的角色提供程序.
That takes care of that problem. Now need a solution for SimpleRolesProvider initialization or else I will have to write my own roles provider.
这个 Scott Allen 的帖子 解决了我所有的问题.
This post by Scott Allen has solved all my problems.
通过在 web.config 中包含它:
By including this in 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 类的所有方法都可用,并且可以在代码中初始化如下:
all the methods of Roles and Membership classes become available and can be initialized in code as follows:
var roles = (SimpleRoleProvider) Roles.Provider;
var membership = (SimpleMembershipProvider) Membership.Provider;
这篇关于使用 simplemembership 在新的 MVC 4 Internet 模板中基于角色的身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!