46

I am using aspx and c# for a setting a authentication cookie for a login.

FormsAuthentication.SetAuthCookie(UserName, True)

I want to store more information in the same cookie. Can I add values to this authentication cookie or do I have to use a second http cookie?

Basically I'm looking for away to store the User's Id so I may be able to access the database using the users table row key

Thanks, Eden

Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
Eden
  • 699
  • 2
  • 12
  • 18

5 Answers5

51

You can add user data to the FormsAuthenticationTicket, then generate the cookie yourself.

There's an example in the the MSDN documentation for FormsAuthenticationTicket.

EDIT

Note that when creating the ticket, you need to set the timeout, which in general you will want to be the same as the value configured in web.config. Unfortunately, in the Framework 3.5 or earlier, the FormsAuthentication class does not expose this timeout publicly. For a workaround, use one of the techniques described in the response to this connect feedback item.

UPDATE

That Connect feedback item is no longer there, sadly. Wish you had briefly described what the techniques were.

Yes, it's a pity Microsoft has discarded historical Connect items. IIRC, the two techniques they suggested were:

  1. Use WebConfigurationManager to read the relevant configuration section and get the timeout value.

  2. Create a cookie using FormsAuthentication.GetAuthCookie, decrypt it using FormsAuthentication.Decrypt and inspect the generated FormsAuthenticationTicket.

Or upgrade to .NET 4.x where there is a FormsAuthentication.Timeout property.

See this question for more info

Community
  • 1
  • 1
Joe
  • 122,218
  • 32
  • 205
  • 338
  • Thanks! this exactly what I was looking for! It seems to overlap the behavior of FormsAuthentication.SetAuthCookie is asp.net 3.5 (I don't have the time to use reflector) with only one small difference. that you can attach arbitrary data to the cookie (not only the name). Thanks Again! – Eden Jul 19 '09 at 17:47
  • That Connect feedback item is no longer there, sadly. Wish you had briefly described what the techniques were... – Roman Starkov May 24 '13 at 12:42
  • 1
    In .NET 4.x, the way to use FormsAuthentication.Timeout when creating a new ticket is like this: DateTime.Now.Add(FormsAuthentication.Timeout) – Lucio Paiva Aug 06 '13 at 20:16
16

You can put whatever you want in the auth cookie as long as it's useful to you. That said, if you're putting sensitive information you should, at the very least, encrypt it, but I'd recommend against putting sensitive information there. You can do something like:

Forms.SetAuthCookie (UserName + "|" + UserId, true);

Then, whenever you need the username or the user id, it is there. Just load the cookie and parse out the values you need.

Again, I'd advise against doing this, especially as I have it presented above. That said, it is possible. You should create accessor methods to pull the data back out:

public int CurrentUserId
{
    get
    {
        int userId = 0;

        if (HttpContext.Current.Request.IsAuthenticated)
        {
            userId = Convert.ToInt32(HttpContext.Current.User.Identity.Name.Split('|')[1]);
        }

        return userId;
    }
}

public string CurrentUserName
{
    get
    {
        string userName = string.Empty;

        if (HttpContext.Current.Request.IsAuthenticated)
        {
            userName = HttpContext.Current.User.Identity.Name.Split('|')[0];
        }

        return userName;
    }
}
andymeadows
  • 1,296
  • 8
  • 14
  • I should note that the way I have presented here is the "expedient" way and will work, but if I were to do it to have a smaller impact on the system as a whole I would use the approach Joe has presented. – andymeadows Jul 12 '10 at 18:05
3

Yes it is smart to use "|" to put more info. If Microsoft have another overloaded method

public static void SetAuthCookie(String userName, bool createPersistentCookie, string userData)`

Then our life will be much easier, our code will be safer.

Emond
  • 50,210
  • 11
  • 84
  • 115
Ryan Liu
  • 55
  • 3
1

Pass that user ID as the userName param.

FormsAuthentication.SetAuthCookie(userId, True)

How are you securing your auth tickets?

user134706
  • 1,010
  • 6
  • 9
  • 5
    I don't want to pass it _instead_ of the name. I would like to add more data to the same authentication cookie. is that possible at all? – Eden Jul 19 '09 at 15:12
  • 1
    @Eden did you solve your issue I am using the same approch but dont no how best to store userId and roles in the same ticket? – c-sharp-and-swiftui-devni Dec 17 '15 at 13:20
0

You can store additional information in the UserData property of the FormsAuthenticationTicket:

using Newtonsoft.Json;
using System.Web;
using System.Web.Security;

public class LoggedInUser
{
    public string FirstName { get; set; } = null;
    public bool IsAdmin { get; set; } = false;
}

public static class Authentication
{
    static void SignIn(
        HttpContextBase context,
        string emailAddress,
        bool rememberMe,
        LoggedInUser user = null)
    {
        var cookie = FormsAuthentication.GetAuthCookie(
            emailAddress.ToLower(),
            rememberMe);
        var oldTicket = FormsAuthentication.Decrypt(cookie.Value);
        var newTicket = new FormsAuthenticationTicket(
            oldTicket.Version,
            oldTicket.Name,
            oldTicket.IssueDate,
            oldTicket.Expiration,
            oldTicket.IsPersistent,
            JsonConvert.SerializeObject(user ?? new LoggedInUser()));

        cookie.Value = FormsAuthentication.Encrypt(newTicket);

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

    static void SignOut(HttpContextBase context)
    {
        FormsAuthentication.SignOut();
    }

    static LoggedInUser GetLoggedInUser()
    {
        if (HttpContext.Current.User?.Identity?.Name != null && HttpContext.Current.User?.Identity is FormsIdentity identity)
            return JsonConvert.DeserializeObject<LoggedInUser>(identity.Ticket.UserData);

        return new LoggedInUser();
    }
}

Further Reading: https://learn.microsoft.com/en-us/aspnet/web-forms/overview/older-versions-security/introduction/forms-authentication-configuration-and-advanced-topics-cs#step-4-storing-additional-user-data-in-the-ticket

dochoffiday
  • 5,515
  • 6
  • 32
  • 41