Ok, so this seems like a common need. A little googling finds a lot of ways to do this. I'm interested in the most "mvc correct" way to do it.
I have, in the upper right hand corner of my app, a greeting that says Hello FirstName LastName
. Now, it's quite easy to get at the username of the logged in user, through the IPrincipal
(aka User.Identity.Name
). However, this won't give me the First and Last name of the user. I have to hit the Membership API to get that.
Hitting the Membership API has its drawbacks. It hits the database every time, which adds an additional db access to every served page. It's easy enough to set some session variables on login, but this only works for that session. If the user clicks the "Remember me", then no login occurs next time and i have to still load these values.
Application_AuthenticateRequest
and hit the membership api and store the values in session variables, or something similar. This is ok, but seems a little brute force.Are there any methods I haven't thought of? And what is the most "mvc correct" way of doing it?
I think the best way is using Cookies. Here is the solution I used in my project:
Create a class to save data in it
[DataContract]
[Serializable()]
public class AuthData {
[DataMember]
public String UserName { get; set; }
[DataMember]
public String FirstName { get; set; }
[DataMember]
public String LastName { get; set; }
[DataMember]
public String Email { get; set; }
// any other property you need to a light-store for each user
public override string ToString() {
string result = "";
try {
using (MemoryStream stream = new MemoryStream()) {
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
result = Convert.ToBase64String(stream.ToArray());
}
} catch (Exception ex) {
throw new HttpException(ex.Message);
}
return result;
}
static public AuthData FromString(String data) {
AuthData result = null;
try {
byte[] array = Convert.FromBase64String(data);
using (MemoryStream stream = new MemoryStream(array)) {
stream.Seek(0, 0);
BinaryFormatter formatter = new BinaryFormatter();
result = (AuthData)formatter.Deserialize(stream, null);
}
} catch (Exception ex) {
throw new HttpException(ex.Message);
}
return result;
}
}
Signin method:
public static bool SignIn(string userName, string password, bool persistent){
if (Membership.ValidateUser(userName, password)) {
SetAuthCookie(userName, persistent);
return true;
}
return false;
}
Setting AuthCookie:
public static void SetAuthCookie(string userName, bool persistent) {
AuthData data = GetAuthDataFromDB(); // implement this method to retrieve data from database as an AuthData object
var ticket = new FormsAuthenticationTicket(
1,
userName,
DateTime.Now,
DateTime.Now.Add(FormsAuthentication.Timeout),
persistent,
data.ToString(),
FormsAuthentication.FormsCookiePath
);
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
cookie.Expires = DateTime.Now.Add(FormsAuthentication.Timeout);
cookie.HttpOnly = false;
cookie.Path = FormsAuthentication.FormsCookiePath;
HttpContext.Current.Response.Cookies.Add(cookie);
}
Getting AuthCookie:
public static AuthData GetAuthCookie() {
if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated && HttpContext.Current.User.Identity is FormsIdentity) {
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
var data = AuthData.FromString(ticket.UserData);
HttpContext.Current.Items["AuthDataContext"] = data;
return data;
}
return null;
}
In ControllerBase:
private AuthData _authData;
private bool _authDataIsChecked;
public AuthData AuthData {
get {
_authData = System.Web.HttpContext.Current.Items["AuthDataContext"] as AuthData;
if (!_authDataIsChecked && _authData == null) {
SignService.GetAuthCookie();
_authData = System.Web.HttpContext.Current.Items["AuthDataContext"] as AuthData;
_authDataIsChecked = true;
}
return _authData;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With