FormsAuthentication after login - c#

Ok, i have simple scenario:
have two pages:
login and welcome pages.
im using FormsAuthentication with my own table that has four columns: ID, UserName, Password, FullName
When pressed login im setting my username like:
FormsAuthentication.SetAuthCookie(userName, rememberMe ?? false);
on the welcome page i cant use:
Page.User.Identity.Name
to provide to user which user currently logged, BUT i dont user username like at all examples in http://asp.net web site i want to user FullName field
i think that always go to db and request fullname when page loads its crazy and dont like to user Sessions or Simple Cookie mayby FormsAuth provider has custom fields for this

I would store the user's full name in the session cookie after your call to FormsAuth
FormsAuth.SetAuthCookie(userName, rememberme);
// get the full name (ex "John Doe") from the datbase here during login
string fullName = "John Doe";
Response.Cookies["FullName"].Value = fullName;
Response.Cookies["FullName"].expires = DateTime.Now.AddDays(30);
and then retrieve it in your view pages via:
string fullName = HttpContext.Current.Request.Cookies["FullName"].Value

Forms authentication works using cookies. You could construct your own auth cookie and put the full name in it, but I think I would go with putting it into the session. If you use a cookie of any sort, you'll need to extract the name from it each time. Tying it to the session seems more natural and makes it easy for you to access. I agree that it seems a waste to go back to the DB every time and I would certainly cache the value somewhere.
Info on constructing your own forms authentication cookie can be found here.

Sorry I'm a little late to the party, but here's how you can do this without storing the value anywhere else :)
var authCookieKey = FormsAuthentication.FormsCookieName;
var responseCookies = HttpContext.Current.Response.Cookies;
var requestCookies = HttpContext.Current.Request.Cookies;
var aspxAuthCookieInResponse = responseCookies.AllKeys.Contains(authCookieKey) ? responseCookies[authCookieKey] : null;
var aspxAuthCookieInRequest = requestCookies.AllKeys.Contains(authCookieKey) ? requestCookies[authCookieKey] : null;
// Take ASPXAUTH cookie from either response or request.
var cookie = aspxAuthCookieInResponse ?? aspxAuthCookieInRequest;
var authTicket = FormsAuthentication.Decrypt(cookie.Value); // Todo: Check for nulls.
// Using the name!
var userName = authTicket.Name;

There are no custom fields for forms authentication. You'll just have to use session. That's what it's there for you know. ;) Just don't forget - forms authentication cookie and session are two independant things. They even each have their own timeouts. So the session won't be reset when a user logs out unless you do so yourself.

What about using Profiles to store the extra info with the User?

The simplest option is to use the session. By default session state is stored in memory and will be lost when the ASP.NET worker process recycles, however you can configure it to use state service instead, which retains session info in a separate process:
http://msdn.microsoft.com/en-us/library/ms178586.aspx
Another option would be to use profiles. As it sounds like you already have 'profile' information stored in your own tables, you'd probably have to write a custom provider for it so it's a more complex solution.

Related

MVC logout all active sessions after same user login

I have c# mvc web application.There is simple login page according to email and password. Now I have a need like that:
When a user login to the system, all active sessions that same email address will logout.
How can I achieve this?
You can use Session.Abandon() or Clear() to abandon the current session, but if there are multiple people logged in with the same address, this will not address that.
You'd have to build that detection in; for instance, you could update a flag on the table that represents your users and then in the other user's sessions periodically check the table if they were re-logged in. OR when a user logs in, create a token in a database table with an expiration date; associate that token to a user in a cookie. When logged out or logging back in, you could invalidate the token associated to that email address, and each user, when they attempt to access the application, could be rejected by your application checking whether the token is expired.
The Abandon method should work (MSDN):
Session.Abandon();
If you want to remove a specific item from the session use (MSDN):
Session.Remove("YourItem");
If you just want to clear a value you can do:
Session["YourItem"] = null;
If you want to clear all keys do:
Session.Clear();
If none of these are working for you then something fishy is going on. I would check to see where you are assigning the value and verify that it is not getting reassigned after you clear the value.
Simple check do:
Session["YourKey"] = "Test"; // creates the key
Session.Remove("YourKey"); // removes the key
bool gone = (Session["YourKey"] == null); // tests that the remove worked

How to Generate a new Session ID

Is it possible to generate a new ID for the session using ASP.NET?
I want it to change when someone logs in to my website just before I set their initial session variables.
You can do this using the SessionIdManager class:
SessionIDManager manager = new SessionIDManager();
string newID = manager.CreateSessionID(Context);
bool redirected = false;
bool isAdded = false;
manager.SaveSessionID(Context, newID, out redirected, out isAdded);
[Code sample is from Anas Ghanem's article]
you can use
SessionIDManager.CreateSessionID Method : returns a unique session identifier that is a randomly generated number encoded into a 24-character string.
Code
SessionIDManager Manager = new SessionIDManager();
string NewID = Manager.CreateSessionID(Context);
string OldID = Context.Session.SessionID;
bool redirected = false;
bool IsAdded = false;
Manager.SaveSessionID(Context, NewID,out redirected, out IsAdded);
Here you can find full detail about hsi : Changing the session ID programmatically.
yes it is possible to generate new ID for the session.
below is one example
SessionState.SessionIDManager Manager = new SessionState.SessionIDManager();
string NewID = Manager.CreateSessionID(Context);
string OldID = Context.Session.SessionID;
bool IsAdded = false;
Manager.SaveSessionID(Context, NewID, false, IsAdded);
Response.Write("Old SessionId Is : " + OldID);
if (IsAdded) {
Response.Write("<br/> New Session ID Is : " + NewID);
}
else {
Response.Write("<br/> Session Id did not saved : ");
}
The ASP.Net session management infrastructure does not expose a supported way to change your session id during the handling of a request. If writing supported code is important to you, there are several things to be aware of with the accepted answer.
Both CreateSessionID and SaveSessionID are marked "This method is not intended to be called from application code".
The SessionID provider is a pluggable type (see e.g. Implementing a custom SessionIDManager), so at the very least you would need to instantiate the correct type.
The session state attached to the HttpContext will remain associated with the initial session id, so anything you put in the session state bag will appear to be lost. Since there isn't anything you can do with the session once you've changed your id, it's kind of pointless to change your id this way.
Unfortunately, there isn't a supported way to do this without a round-trip. What you need to do is to wipe the session state cookie when you generate the login form. When the user submits the form back, the framework will call into the SessionIDManager to generate a new one. Wiping the session cookie correctly is slightly more complicated than most of the code samples show. The cookie name is another parameter configurable in the web.config. You need to read it from the configuration by accessing the property:
((System.Web.Configuration.SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState")).CookieName
The session id cookie is not scoped to the application, so if there are two applications installed on the same server it's often desirable to have them use different cookie names, so this is required more commonly than you might think.
I assume this is security related? Will a Session.Clear() or Session.Abandon() work for you? This is a good SO link related to those methods.
Otherwise, it is difficult because the ASP.NET session cookie is already on the user's browser. You might not have confidence that the session was truly changed.

MVC 3 razor Storing user name of visitor via Windows Authentication using sessions

I was trying to set a session in mvc to store the current user that visited the site. For example:
A user visits the site.
It gets recorded to the database as a login.
When the user closes his browser. The session is over.
With Windows Authentication I can get the user name with this
User.Identity.Name
In the _layout I was hoping I could do this:
#{
var Data = HttpContext.Current.Session["UserSession"];
Data["UserSession"] = User.Identity.Name;
}
But I cant. What is the proper syntax to set up a session variable and assing it a value of my user's identity.
HttpContext.Current.Session["MySessionVariable"] = User.Identity.Name;
If thats not what you need then i need more clarification on what your asking

InitializeCulture change language of domain

I have a MasterPage with a combo with languages, the thing is that I would like to assign a default language the moment a user starts the application, after that the user can change between languages. What I understand is that I have to override InitializeCulture method on all of the pages, the problem is, where I can save the selected language? When I use Cache["Culture"] all of the user that starts the application shares the same Cache and overrides the value for all the users logged in.
How can I do that? or how can I save data for a single user's thread when it's not logged in?
Thanks in advance for any help.
use the Session object for data specific to sessions, if you need to persist the choice beyond the session you will need to store it with whatever user data you have
Session["Culture"] = yourculturevar;
If you want to save information locally to a user's computer (as opposed to saving something in a database on the server for logged in users), you can use cookies.
Setting a Cookie
private void SetLanguageCookie(string language)
{
HttpCookie cookie = new HttpCookie("UserSelectedLanguage", language);
// Optionally set expiration for cookie
cookie.Expires = DateTime.Now.AddDays(30);
}
Retrieving a Cookie
private string GetLanguageCookie()
{
HttpCookie cookie = Request.Cookies["UserSelectedLanguage"];
return cookie.Value;
}

Can't set FormsAuthenicationTicket.UserData in cookieless mode

I'm trying to implement the "Writing Information to UserData" section of this article, but it doesn't work properly when the cookie is part of the URI.
My code:
// Create the cookie that contains the forms authentication ticket
HttpCookie authCookie = FormsAuthentication.GetAuthCookie( userName, createPersistantCookie );
// Get the FormsAuthenticationTicket out of the encrypted cookie
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt( authCookie.Value );
// Create a new FormsAuthenticationTicket that includes our custom User Data
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket( ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, "foo");
// Update the authCookie's Value to use the encrypted version of newTicket
authCookie.Value = FormsAuthentication.Encrypt( newTicket );
// Manually add the authCookie to the Cookies collection
HttpContext.Current.Response.Cookies.Add( authCookie );
// Determine redirect URL and send user there
string redirUrl = FormsAuthentication.GetRedirectUrl( userName, createPersistantCookie );
HttpContext.Current.Response.Redirect( redirUrl, false );
When cookieless is used, the page redirects but doesn't get the correct URI with the cookie information in it, so it loops back to my Login page where Request.IsAuthenticated returns false. An endless loop ensues.
How do I redirect to the proper URI?
I found this to be an interesting problem, so I set about doing some digging, testing, and a little bit of debugging into the .net framework source.
Basically, what you are trying to do will not work. Anything you put into the Response.Cookies collection will just be ignored if the browser doesn't support cookies. You can check Request.Browser.Cookies to see if cookies are supported.
In asp.net, both session state and authentication support a cookieless mode, but this does not extend to other cookies. In fact, it seems that session and authentication can be set to different modes of operation themselves even.
The authentication system can store it's own data in the URI, but it does so by directly manipulating the URI itself. Sadly, Microsoft doesn't appear to have exposed these capabilities to code outside the authentication module.
Basically, if you use the methods like FormsAuthentication.GetAuthCookie() and FormsAuthentication.SetAuthCookie() then the authentication system will take care of putting that information into the URI for you automagically... but it doesn't allow you to supply a customized authentication ticket to these methods... so you are stuck with the default auth ticket.In these cases, you are on your own for storing any custom data.
Anyway...
There really isn't much advantage to storing custom data directly in an authentication ticket if the authentication system has gone cookieless... in cookieless mode, things like "persistant cookie" have no meaning so you'll be regenerating the data at least once per session anyway.
The most common suggestion for cases where you are cookieless but still need custom data like this is to enable cookieless sessions, and just store your custom data as a session variable. The session ID will get put into the URI, but the custom data will stay in memory on the server. The usage pattern is identical no matter if your sessions are cookieless or not.
If you really wanted to, you could come up with a system of storing the custom data in the URI manually. The easiest thing to do would be to put the custom data into query strings or use pathdata. I can't see any real advantage to this over sessions variables unless you are just deperate not to use server memory (adding a little memory to a server is cheap, ugly URLs and manually writing code to deal with them is not cheap).
Thank you for the great explanation, Stephen. In cases where the user does not allow cookies, I'm just going to have to avoid the UserData and load the data from the database.
Before the code listed above I'll do:
if( !HttpContext.Current.Request.Browser.Cookies || !FormsAuthentication.CookiesSupported )
{
FormsAuthentication.RedirectFromLoginPage( userName, false);
return;
}

Categories