【问题标题】:FormsAuthentication Roles without Membership没有成员资格的 FormsAuthentication 角色
【发布时间】:2013-06-05 18:38:20
【问题描述】:

我正在尝试使用 FormsAuthentication,目前使用用户名和密码可以正常工作。我需要将用户角色添加到表单身份验证票证中,并且我没有使用 ASP.NET 成员资格。

if (rep.CheckUser(model.UserName, model.Password,out UserRole))//Check User
  {

  FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

 // Roles.AddUserToRole(model.UserName, UserRole);//This Requires Membership

  return Redirect(FormsAuthentication.DefaultUrl);

 }

【问题讨论】:

  • 您现在使用哪种机制来处理角色?
  • @HuseinRoncevic 在我的数据库表中,我有一个用户的用户名、密码和角色。我想将从数据库表中检索到的角色传递给身份验证票
  • 不确定它是否有效。您只需将用户名放在 auth cookie 中,然后对于每个传入请求,您从 auth cookie 中读取用户名并从数据库加载其他详细信息。这可以在ActionFilter 中完成。

标签: asp.net asp.net-mvc login asp.net-membership forms-authentication


【解决方案1】:

FormsAuthenticationTicket 构造函数(参数最多的那个)有userData 参数,它接受一个字符串。在这里,您可以添加您的角色,由管道 (|) 或哈希等字符分隔。您打算如何使用取决于您。您通常会做的是注册AuthenticateRequest 事件。因此,您可以创建一个票证:

private void CreateTicket()
{
    var ticket = new FormsAuthenticationTicket(
            version: 1,
            name: UserName,
            issueDate: DateTime.Now,
            expiration: DateTime.Now.AddSeconds(httpContext.Session.Timeout),
            isPersistent: false,
            userData: String.Join("|", arrayOfRoles));

    var encryptedTicket = FormsAuthentication.Encrypt(ticket);
    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

    httpContext.Response.Cookies.Add(cookie);
}

global.asax 之后你会做这样的事情:

public override void Init()
{
    base.AuthenticateRequest += OnAuthenticateRequest;
}

private void OnAuthenticateRequest(object sender, EventArgs eventArgs)
{
    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
        var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
        var decodedTicket = FormsAuthentication.Decrypt(cookie.Value);
        var roles = decodedTicket.UserData.Split(new[] {"|"}, StringSplitOptions.RemoveEmptyEntries);

        var principal = new GenericPrincipal(HttpContext.Current.User.Identity, roles);
        HttpContext.Current.User = principal;
    }
}

现在您在 IPrincipal 对象 (HttpContext.Current.User) 中拥有角色,当您使用 HttpContext.Current.User.IsUserInRole("RoleName") 进行查询时,您将得到真或假。这样你应该可以避免使用Roles 提供者。

更新:为了处理重新创建用户主体而调用的更好事件是 Application_AuthenticateRequest 而不是 BeginRequest。我已更新代码以反映这一点。

【讨论】:

  • 很好的答案,尽管如果用户未通过身份验证,这会引发空引用异常。请改用base.PostAuthenticateRequest += OnAfterAuthenticateRequest;
  • 好答案。但是,如果您使用的是标准 FormsAuthorization,则无需再次解密票证...您可以简单地说var decodedTicket = ((FormsIdentity)HttpContext.Current.User.Identity).Ticket;
  • 我没有尝试过这个主要是因为我一直在加密票证。不过,我会试一试。谢谢。
  • 好答案,但我想提一下HttpContext.Session.Timeout 时间以分钟为单位(默认为20),因此您应该使用DateTime.Now.AddMinutes(HttpContext.Session.Timeout) 而不是AddSeconds(...)
猜你喜欢
  • 2011-12-22
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 2012-08-12
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多