How does a site such as Stack Overflow pass user information to ASP.NET MVC?

Basically, I enter my site using OpenId, very similar to what I assume. When I get the information back, I drop it into the database and create my "Registered User". I installed my AuthCookie:

FormsAuthentication.SetAuthCookie(user.Profile.MyProfile.DisplayName, false); 

Then I can use this for the username. However, I would like to pass the whole object, not just the string for the display name. So my question is:

How does SO do this?

They extend / override the SetAuthCookie(string, bool) method to accept a User object, i.e. SetAuthCookie(User(object), bool) .

What is the best way to save a User object so that it is available to my UserControl on every page of my web application?

Thanks in advance!

+4
source share
3 answers

You can achieve this behavior by embedding your custom Member Provider or extending an existing one. The provider stores user information based on the key (or simply by user name) and provides access to the MembershipUser class, which you can extend as you wish. Therefore, when you call FormsAuthentication.SetAuthCookie(...) , you basically set the user key, which the provider can access.

When you call Membership.GetUser() , the membership infrastructure will call the underlying provider and call its GetUser(...) method, giving it the key of the current user. This way you get the current user object.

+3
source

Jeff,

As I said in the comments on your question above, you should use the ClaimedIdentifier for the username, i.e. the first SetAuthCookie parameter. There is a huge reason for this. Feel free to start the topic on dotnetopenid@googlegroups.com if you want to learn more about the reasons.

Now about your question about the whole user object ... if you want to send this as a cookie, you will have to serialize your user object as a string, then you have to sign it somehow to protect it from user intervention. You can also encrypt it. Blah blah, this is a lot of work, and in the end you will have a big cookie going back and forth with every web request you don’t want.

What I do in my applications to solve the problem you are reporting is adding a static property to my Global.asax.cs file called CurrentUser. Like this:

 public static User CurrentUser { get { User user = HttpContext.Current.Items["CurrentUser"] as User; if (user == null && HttpContext.Current.User.Identity.IsAuthenticated) { user = Database.LookupUserByClaimedIdentifier(HttpContext.Current.User.Identity.Name); HttpContext.Current.Items["CurrentUser"] = user; } return user; } } 

Note that I cache the result in the HttpContext.Current.Items dictionary, which is specific to only one HTTP request, and keeps the user from choosing until one hit - and only retrieves it for the first time if the page really wants CurrentUser information.

Thus, the page can easily obtain the current registration of user data as follows:

 User user = Global.CurrentUser; if (user != null) { // unnecessary check if this is a page that users must be authenticated to access int age = user.Age; // whatever you need here } 
+2
source

One way is to introduce a class controller into the controller, which is responsible for obtaining information for the current registered user. Here is how I did it. I created a class called WebUserSession that implements the IUserSession interface. Then I just use dependency injection to inject it into the controller when creating the controller instance. I implemented a method on my interface called GetCurrentUser that will return a User object, which I can then use in my actions, if necessary, passing it to the view.

 using System.Security.Principal; using System.Web; public interface IUserSession { User GetCurrentUser(); } public class WebUserSession : IUserSession { public User GetCurrentUser() { IIdentity identity = HttpContext.Current.User.Identity; if (!identity.IsAuthenticated) { return null; } User currentUser = // logic to grab user by identity.Name; return currentUser; } } public class SomeController : Controller { private readonly IUserSession _userSession; public SomeController(IUserSession userSession) { _userSession = userSession; } public ActionResult Index() { User user = _userSession.GetCurrentUser(); return View(user); } } 

As you can see, now you will have access to the user, if necessary. Of course, you can change the GetCurrentUser method to first view the session or some other means if you want, so you are not going to the database all the time.

+1
source

All Articles