【问题标题】:MVC Update FormsAuthenticationTicket UserData at RuntimeMVC 在运行时更新 FormsAuthenticationTicket UserData
【发布时间】:2013-01-29 03:00:17
【问题描述】:

我正在编写一个带有自定义身份验证和授权MVC 4 Web 应用程序。当用户登录网站时,我会创建一个 FormsAuthenticationTicket 并将其存储在 cookie

public void SignIn(string userName, bool createPersistentCookie, string UserData)
{
    if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");

    // Create and tuck away the cookie
    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddDays(15), createPersistentCookie, UserData);
    // Encrypt the ticket.
    string encTicket = FormsAuthentication.Encrypt(authTicket);

    //// Create the cookie.
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    HttpContext.Current.Response.Cookies.Add(faCookie);
}

UserData 字符串将是一个以竖线分隔的字符串,并且始终包含至少两项,UserID |用户角色。可以为用户分配一个或多个角色,因此,UserData 可能看起来像这样 UserID |用户角色 |用户角色 |用户角色

然后我在 Global.asax 中有我自己的自定义 通用主体

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{

        // Get the authentication cookie
        string cookieName = FormsAuthentication.FormsCookieName;
        HttpCookie authCookie = Context.Request.Cookies[cookieName];

        // If the cookie can't be found, don't issue the ticket
        if (authCookie == null) return;

        // Get the authentication ticket and rebuild the principal
        // & identity
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        string[] UserData = authTicket.UserData.Split(new Char[] { '|' });

        GenericIdentity userIdentity = new GenericIdentity(authTicket.Name);
        GenericPrincipal userPrincipal = new GenericPrincipal(userIdentity, UserData);
        Context.User = userPrincipal;
}

这一切都很好,但是,在我的应用程序中,如果用户有多个角色,当他们登录时,我需要列出他们的角色,然后让他们只选择一个角色去执行基于所选角色的功能角色。

我在想,要做到这一点,也许我可以将用户选择的角色传递给一个方法,获取他们的 FormsAuthenticationTicket 并更新 UserData 以反映他们的角色已经选择了。例如,使用 1|Manager|Applicant 创建一个 UserData 字符串,然后我需要列出这两个角色并询问用户他们想要在哪个角色下执行功能,他们选择 Manager,然后我将其 FormsAuthenticationTicket 中的 UserData 更新为 1|Manager

这是否可能,或者有更好的方法来做到这一点?

任何帮助将不胜感激。

谢谢大家。

【问题讨论】:

  • 这似乎是非常不直观的行为。所以用户必须注销并重新登录才能进行其他活动?最好让用户做他们被允许做的事情,而不是让他们跳槽。这只是可用性差。

标签: asp.net asp.net-mvc asp.net-mvc-4 forms-authentication


【解决方案1】:

你可以随时更改FormsAuthenticationTicket

HttpCookie cookie = FormsAuthentication.GetAuthCookie(Username, true);
var ticket = FormsAuthentication.Decrypt(cookie.Value);

var newticket = new FormsAuthenticationTicket(ticket.Version,
                                              ticket.Name,
                                              ticket.IssueDate,
                                              ticket.Expiration,
                                              true, 
                                              "new user data",
                                              ticket.CookiePath);

cookie.Value = FormsAuthentication.Encrypt(newticket);
cookie.Expires = newticket.Expiration.AddHours(24);
HttpContext.Current.Response.Cookies.Set(cookie);

【讨论】:

    【解决方案2】:

    正如我在评论中所说,我觉得这是非常糟糕的可用性。但是,如果您决心这样做,那么 Dzenan 的方法会奏效(您基本上只是在用户选择了他想要的角色后去掉所有其他角色)。

    另一种方法是向您的用户数据添加一个附加字段,即 SelectedRole。然后创建一个包含此字段的自定义 IPrincipal。

    另一种方法是将其存储为您自己的 cookie,尽管我会确保您确认您没有设置用户未获得授权的角色(即,如果您设置 SelectedRole=Admin 确保用户在使用之前具有管理员角色)。

    【讨论】:

    猜你喜欢
    • 2014-03-08
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    相关资源
    最近更新 更多