ASP.Net Store User Data in Auth Cookie
Asked Answered
H

6

26

I want to store some data like the user nickname and user ID (table primary key) in the user data section of the auth cookie. The reason I'm doing this is to retain this data when the browser is closed, without having the user relogin.

Edit: Whoops! Realized I'd not explained myself well. I am not trying to reauthenticate a user based on their cookie. The user is already authenticated by ASP.Net's membership system - this part is fine. My problem is that if I want to show the user's nickname, for example, I have to fire off another SQL query, and then store it in the session. I figured it would make sense to store this information in the auth cookie (again, the one already created by ASP.Net) in the UserData section, which seems to have been created for this purpose.

I don't want to use profiles because I have my own user table with profile data, and I needed a lightweight solution.

What is a good way to encode this data in the user data section of the auth cookie? I was thinking serialization, but that might be overkill. Am I going about this the wrong way?

Hae answered 1/7, 2009 at 17:37 Comment(0)
M
38

I've written an in depth tutorial on how to do this here:

http://www.danharman.net/2011/07/07/storing-custom-data-in-forms-authentication-tickets/

This maintains the encryption and authentication, and uses json to serialize a class into the UserData field.

Edit:

The blog no longer exists, an archive can be found on the web archive here.

Summary from blog:

Get the existing cookie and auth ticket

HttpResponse response = HttpContext.Current.Response;
bool rememberMe = true;
var cookie = FormsAuthentication.GetAuthCookie(name, rememberMe);
var ticket = FormsAuthentication.Decrypt(cookie.Value);

Define your custom data (make sure this is serializable to json)

var userData = new YourUserClass(...);

Create a new auth ticket with your data, and existing auth ticket settings

var newTicket = new FormsAuthenticationTicket(ticket.Version, 
    ticket.Name, 
    ticket.IssueDate, 
    ticket.Expiration, 
    ticket.IsPersistent, 
    userData.ToJson(), //This is where you'd set your user data
    ticket.CookiePath);
var encTicket = FormsAuthentication.Encrypt(newTicket);

Set your customized ticket into cookie and add to response

cookie.Value = encTicket;
response.Cookies.Add(cookie);
M16 answered 7/7, 2011 at 0:19 Comment(6)
Fantastic solution. Even without the json serialization piece, this is a great way to set the UserData string and maintain other default/configured values despite forms auth's horrible API.Celio
Your answer seems to do exactly what I had intended at the time! Thanks!Hae
This answer would be more useful if it sumarised your post as well as linking to it. If your webserver gets hit by a bus, this answer will stop being helpful.Stallion
@RichardGarside good point. This appears to be the case as the link now displays an empty page.Stores
Not sure whats going on as I had to hit refresh to get it to load but seems ok now. I'll bounce the wordpress and see if that sorts it as its probably todo with the page caching addin. As to pasting the whole article in, its long and necessarily so I don't see a reasonable way of shortening it to fit as an answer here.M16
@M16 u still around I am using ur solution but im trying to config it for webforms how does one retreieve the data using the method in link u suggested specifically userdataFezzan
H
10

Apparently I was on the right track: http://www.asp.net/learn/security/tutorial-03-vb.aspx (Step 4: Step 4: Storing Additional User Data in the Ticket)

Hae answered 3/7, 2009 at 17:38 Comment(0)
A
3

Yes. If you are storing the User ID and Login in the cookie what's stopping someone from changing their cookies to anyone's User ID and Login?

You need to set up an auth ticket system. Basically it's a cookie value that gets checked when no session exists. If a value is present you run that against a ticket table which should contain their User ID. If you find the ticket, give them a session and a new ticket.

Ashantiashbaugh answered 1/7, 2009 at 17:42 Comment(1)
Hmm...I'm sure ASP.Net is already reisuing a new ticket when a user reauthenticates browser based on their auth cookie. However, I believe that you're also suggesting that even the encrypted User ID stored in the user data might be substituted by the malicious user's own encrypted data stored in his auth cookie? But then I'm not sure I follow the point of the userdata section in the auth cookie at all!Hae
R
3

If you've already got a user table with profile information in it, why don't you hook into it with a custom profile provider.

If you want another example of how to implement something like this, you could take a look at the SQL Table Profile Provider

Resonator answered 1/7, 2009 at 21:3 Comment(0)
L
2

Maybe you could just create another cookie... I personally wouldn't mess with the auth cookie.

Les answered 1/7, 2009 at 17:41 Comment(4)
Actually I AM generating a new auth cookie. I can go ahead and store a simple text string in the UserData section of the new cookie. My question is about serializing more complex objects.Hae
I meant a cookie in addition to the auth cookie. Leave the auth cookie alone and create a new unencrypted cookie for the temporary user data.Les
Nah, I would be storing the User ID and Nickname - wouldn't want to store such sensitive data without encryptionHae
The encryption provided by storing info in the auth cookie is not going to be adequate. If you consider this information 'sensitive' then don't store it in a cookie.Stallion
M
0

Storing extra user data in the cookie means a larger cookie that is sent back and forth from the client with every request.

A better approach to avoid the extra database hits you are worried about is to cache that data in memory after the user logs in.

ASP.NET has a per request cache HttpContext.Current.Items and a app domain cache HttpContext.Current.Cache, I think you are looking for HttpContext.Current.Cache in this instance.

Alternatively if you need caching across web servers (load balanced web servers) you can look into 3rd party key value stores like like memcached, redis, velocity, ncache etc.

Millenarian answered 24/10, 2012 at 2:6 Comment(1)
how is this different from session variablesConcavoconvex

© 2022 - 2024 — McMap. All rights reserved.