在我的UserController.Login
操作中,我尝试使用用户实体的导航属性AddUserToRole()
之一的值来获取经过身份验证的用户:MembershipType.MembershipName
Roles.AddUserToRole(thisUser.UserName, thisUser.MembershipType.MembershipName);
我没有使用臃肿的自动生成的成员资格类型,只是想将文本值添加到用户的角色 - 而不是一系列角色。用户 --> 一个角色。
为了解决这个问题,我在 web.config 中定义了一个自定义角色提供程序:
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
<providers>
<clear/>
<add name="CustomRoleProvider"
type="MyWebsite.CustomRoleProvider,
CustomMembershipEF, Version=1.0.0.0, Culture=neutral"
connectionStringName="MyDbContext"
enablePasswordRetrieval="false" enablePasswordReset="true"
requiresQuestionAndAnswer="false" writeExceptionsToEventLog="false" />
</providers>
</roleManager>
所以调用 Roles.AddUserToRole() 会调用我的自定义提供程序中的方法,但我不确定在该方法中要做什么。
之前我只是添加enabled="true"
到rolemanager
web.config 中的部分,但收到以下错误:
找不到请求的 .Net Framework 数据提供程序。它可能没有安装。
这是我的自定义角色提供程序(虽然我不知道为什么需要它,因为我只想添加角色名称):
public class CustomRoleProvider : RoleProvider
{
public override bool IsUserInRole(string username, string roleName)
{
using (var db = new MyApp.DAL.MyAppDbContext())
{
var user = db.Users.SingleOrDefault(u => u.UserName == username);
if (user == null)
return false;
if (user.MembershipType != null && user.MembershipType.MembershipName == roleName)
{
return true;
}
}
return false;
}
public override string[] GetRolesForUser(string username)
{
using (var db = new MyApp.DAL.MyAppDbContext())
{
var user = db.Users.SingleOrDefault(u => u.UserName == username);
if (user == null)
return new string[] { };
return db.MembershipTypes == null ? new string[] { } :
db.MembershipTypes.Select(u => u.MembershipName).ToArray();
}
}
// -- Snip --
public override string[] GetAllRoles()
{
using (var db = new MyApp.DAL.MyAppDbContext())
{
return db.MembershipTypes.Select(r => r.MembershipName).ToArray();
}
}
// -- Snip --
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
我认为这应该很容易完成 - 只需设置用户的角色名称......感谢您的帮助。
- 更新 -
我把自定义方法的内容注释掉了AddUserToRole()
,用户就可以登录了。但是,在调用操作方法时,没有执行角色检查 - 即。应该失败,因为角色名称实际上并不存在:
[HttpGet]
[AllowAnonymous]
[Authorize(Roles="WaitConfirmationxxx")]
public ActionResult WaitConfirmation()
{
我还注意到IsInRole()
调用了在其中执行 db 调用的自定义GetRolesForUser()
方法。不完全是最佳的,想知道这是否真的应该是这样的?
if(User.IsInRole("WaitConfirmation"))
{
// email address has not yet been confirmed
return RedirectToAction("WaitConfirmation", "User");
}
- 更新 -
我的错误是认为我需要使用Roles.AddUserToRole()
(除非有人另有评论)。
我还在web.configcacheRolesInCookie
的定义中添加了参数:roleManager
<roleManager enabled="true" defaultProvider="CustomRoleProvider" cacheRolesInCookie="true">
所以现在当我打电话时 if(User.IsInRole("WaitConfirmation"))
,我的自定义GetRolesForUser(string username)
被调用了。
现在的问题是这些Authorization
属性都不起作用。建议?