首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用自定义用户主体获取自定义角色提供程序

如何使用自定义用户主体获取自定义角色提供程序
EN

Stack Overflow用户
提问于 2012-08-17 21:06:25
回答 1查看 2.5K关注 0票数 2

长期潜伏的第一次海报..

尝试为MVC实现一个简单的自定义角色和成员资格提供程序。

我已经实现了角色和成员资格提供程序类,并将它们挂钩到我的web.config中。添加代码来根据自定义数据库验证我的用户,它工作得很好。

然而,我不喜欢我的角色提供者在每次请求时访问数据库的方式,所以我添加了一些代码来尝试从身份验证票证中读取,如下所示:

自定义角色提供程序:

代码语言:javascript
复制
public override string[] GetRolesForUser(string username)
   {
       if (HttpContext.Current.User != null)
       {
           return ((UserPrincipal)HttpContext.Current.User).Roles.ToArray();
       }
       else
       {
           UserPrincipal user = orchestrator.GetUserByLoginID(username);
           return user.Roles.ToArray();
       }
   }

然后,我在global.asax中添加了以下代码,以便使用自定义用户主体对象将角色和其他一些有用的用户信息持久化到cookie中:

代码语言:javascript
复制
protected void Application_AuthenticateRequest(Object sender, EventArgs e) 
    {
        HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket =      FormsAuthentication.Decrypt(authCookie.Value);

            JavaScriptSerializer serializer = new JavaScriptSerializer();

            UserPrincipalModel userFromTicket = serializer.Deserialize<UserPrincipalModel>(authTicket.UserData);

            UserPrincipal newUser = new UserPrincipal();
            newUser.UserId = userFromTicket.UserId;
            newUser.FullName = userFromTicket.Fullname;
            newUser.Email = userFromTicket.Email;
            newUser.Roles = userFromTicket.Roles;
            newUser.Identity = new GenericIdentity(userFromTicket.Username);

            HttpContext.Current.User = newUser;
        }
    }

我的用户主体类:

代码语言:javascript
复制
  public class UserPrincipal : IPrincipal
{
    public UserPrincipal() { }
    public UserPrincipal(int userId, string userName, string fullName, string password)
    {
        UserId = userId;
        UserName = userName;
        FullName = fullName;
        Password = password;
    }
    public virtual int UserId { get; set; }
    public virtual string UserName { get; set; }
    public virtual string FullName { get; set; }
    public virtual string Email { get; set; }
    public virtual string Password { get; set; }        
    public virtual IEnumerable<string> Roles { get; set; }

    public virtual IIdentity Identity { get; set; }

    public virtual bool IsInRole(string role)
    {
        if (Roles.Contains(role))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

   //public string[] GetRolesForUser()
   //{
   //    return Roles;
   //}
}

但是,当我运行此命令时,当角色提供程序尝试访问cookie中的自定义UserPrincipal对象时,我得到以下错误

“无法将'System.Web.Security.RolePrincipal‘类型的对象强制转换为’MyApp.Domain.UserPrincipal‘类型”

它就像自定义角色提供者正在用它自己的角色特定的主体重写存储在票证中的自定义用户主体im。

我只是想知道我正在尝试做的是不是有缺陷,或者是否有更简单的方法。我不想重复发明轮子。

谁有一个自定义角色提供程序的示例,它不会在每个角色请求中都命中数据库?

EN

回答 1

Stack Overflow用户

发布于 2012-11-14 05:49:04

请在此处进行更改:

代码语言:javascript
复制
protected void Application_AuthenticateRequest(Object sender, EventArgs e) 

就在这里:

代码语言:javascript
复制
protected void Application_PostAuthenticateRequest(object sender, EventArgs e)

基本上,默认角色提供程序的内部工作是在您设置HttpContext.Current.User属性之后设置该属性,从而覆盖您所做的操作。

您也可以尝试清除默认的角色提供程序,它似乎在mvc3和asp.net web表单中有效,但在MVC4中失败。

代码语言:javascript
复制
<membership>
  <providers>
    <clear />
  </providers>
</membership>
<profile>
  <providers>
    <clear />
  </providers>
</profile>
<roleManager enabled="false">
  <providers>
    <clear />
  </providers>
</roleManager>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12006429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档