How to get recently authenticated user?

2019-02-28 13:12发布

问题:

I am working with MVC 3 and I have just implemented a wrapper for the FormsAuthenticationService.

Something similar to the following.

public void SignIn(string username, bool createPersistantCookie)
{
    if (string.IsNullOrEmpty(username)) 
        throw new ArgumentException("Value Cannot be null or empty", "username");

    FormsAuthentication.SetAuthCookie(username, createPersistantCookie);
}

Reluctantly, I have gotten this to work, but now I am not quite sure how to get the information that I have stored.

Once the user is in my system, how can I now safely retrieve this information if I need to grab their UserID out of the database?

回答1:

Based on the additional information provided, you want to store additional data with the FormsAuthentication ticket. To do so, you need first create a custom FormsAuthentication ticket:

Storing Data

Grab the current HttpContext (not worrying about testability)

var httpContext = HttpContext.Current;

Determine when the ticket should expire:

var expires = isPersistent 
                ? DateTime.Now.Add(FormsAuthentication.Timeout) 
                : NoPersistenceExpiryDate; // NoPersistenceExpiryDate = DateTime.MinValue

Create a new FormsAuthentication ticket to hold your custom data.

var authenticationTicket = new FormsAuthenticationTicket(
                             1, 
                             username, 
                             DateTime.Now, 
                             DateTime.Now.Add(FormsAuthentication.Timeout), 
                             isPersistent, 
                             "My Custom Data String"); //Limit to about 1200 bytes max

Create your HTTP cookie

new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authenticationTicket))
  {
    Path = FormsAuthentication.FormsCookiePath,
    Domain = FormsAuthentication.CookieDomain,
    Secure = FormsAuthentication.RequireSSL,
    Expires = expires,
    HttpOnly = true
  };

And finally add to the response

httpContext.Response.Cookies.Add(cookie);

Retrieving Data

Then you can retrieve your data on subsequent requests by parsing the stored authentication ticket...

Again, grab current HttpContext

var httpContext = HttpContext.Current

Check to see if the request has been authenticated (call in Application_AuthenticateRequest or OnAuthorize)

if (!httpContext.Request.IsAuthenticated)
    return false;

Check to see if you have a FormsAuthentication ticket available and that it has not expired:

var formsCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
if (formsCookie == null)
  return false;

Retrieve the FormsAuthentication ticket:

var authenticationTicket = FormsAuthentication.Decrypt(formsCookie.Value);
if (authenticationTicket.Expired)
  return false;

And finally retrieve your data:

var data = authenticationTicket.UserData;


回答2:

You haven't actually stored a user id in the database. All the code that you've written does is store an authentication cookie on the users computer, either as a session cookie (not persistent) or as a persistent one.

When your page refreshes, it will get the cookie automatically, decode it, and populate the IPrincipal object which you access from the User.Current property of your controller.