Cookies in ASP.Net MVC 5 - c#

I am developing an application in which users are SignUp or SignIn by External Identity Providers like AAD, Google, WS-Federated Authentication etc. Now I want to create cookies on a user machine to logged in until user SignOut. Give me some thought and guide me how I can overcome it. thanks in advance.

Use Request.Cookies and Response.Cookies to handle your situation. once user coming back from third party authorization create cookie and store it in browser and once user Logout clear the cookie.
string cookievalue ;
if ( Request.Cookies["cookie"] != null )
{
cookievalue = Request.Cookies["cookie"].Value.ToString();
}
else
{
Response.Cookies["cookie"].Value = "cookie value";
}
For removing cookie use following code
if (Request.Cookies["cookie"] != null)
{
Response.Cookies["cookie"].Expires = DateTime.Now.AddDays(-1);
}

Related

Creating an HttpCookie that is not bound to a session or a domain?

I'm trying to pass a cookie from one application to the other. The two applications are on separate servers. The first application (SharePoint site) opens the second one in a popup. Before the site is opened, a cookie should be dropped into the browser which contains the username and password of the logged in user (in SharePoint) - of course, the value of the cookie is encrypted for security purposes.
On the other side, in the second application which is an ASP.NET MVC3 web application, I created an HttpModule which tries to locate this cookie in the browser, decrypt the contents and authenticate the user against some user store exposed by a WCF service.
Here's the code in the module:
void httpApplication_AuthenticateRequest(object sender, EventArgs e)
{
HttpApplication httpApplication = sender as HttpApplication;
if (httpApplication != null)
{
HttpCookie authCookie = httpApplication.Context.Request.Cookies["SPAuthentication"];
if (authCookie != null)
{
String cookievalue = EncryptionManager.Current.DecryptStringAES(authCookie.Value, "p#s$w0Rd_Mo3T");
String[] parts = cookievalue.Split(';');
if (parts.Length == 2)
{
String username = this.GetToken(parts[0]);
String password = this.GetToken(parts[1]);
FedAuthentication.Current.Signin(String.Format(#"{0}\IPREmployee", username), password);
httpApplication.Context.Request.Cookies.Remove("SPAuthentication");
}
}
}
}
The authCookie is always null although I can actually see the cookie in the browser (using FireBug). One thing I noticed is that the cookie is bound to the session, so it should expire with the session. I thought this could be the issue. Then I did some research and found out that ASP.NET does not allow cross-domain cookies. So is there a way around this?
P.S: I do not have access to the source-code of the SharePoint application so I cannot be sure what's going on there. The only thing I'm sure of is that the cookie is actually being dropped into the browser.

Windows identity foundation - sign out or update claims

I am using Windows Identity foundation to manage login to our site.
When a user logs in i am using some information in his request to put into the claims.
It is all working fine, but now I need to manage this scenario:
user is already logged in, athenticated and has a valid token.
But user decides to browses in again (via a redirect from another site)
So his information in his request is different.
I want to either
Sign him out - so that he naturally creates a new token with his new information
OR update his existing token.
So my question is:
How do i Sign out of Windows Identity foundation?
Or How do I update the existing claims?
I have tried this code:
public void ExpireClaims(HttpContextBase httpContextBase)
{
var module =
httpContextBase.ApplicationInstance.Modules["WSFederationAuthenticationModule"] as
WSFederationAuthenticationModule;
if (module == null)
{
return;
}
module.SignOut(true);
}
But module is alway null.
and i tried this:
public void FederatedSignOut(string replyUrl)
{
WSFederationAuthenticationModule.FederatedSignOut(null, new Uri(replyUrl));
}
But i get a null reference execption when i do this.
Thanks very much.
Essentially sign-out is just deleting the cookie so:
FormsAuthentication.SignOut
or
FederatedAuthentication.SessionAuthenticationModule.SignOut
or
FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie
will work.
Or use the FederatedPassiveSignInStatus (should be in your Toolbox). Set the property SignOutAction to FederatedSignOut and the control will clear out your STS session as well.

What is the best way to identify logged user?

I was looking for the efficient way to track the logged users when using asp.net login control
if (!IsPostBack)
{
if (Membership.GetUser() != null)
{
var user = Membership.GetUser();
Session["user"] = user;
}
else
{
Session["user"] = "";
}
}
Any suggestions will be appreciated
why all this pain and why do you try to save it in the Session (which is user specific and not application specific), when you can simply get it from this object:
HttpContext.Current.User
check this one for details: How to get current user who's accessing an ASP.NET application?
You can get the user identity (if you're using asp.net forms membership) through:
HttpContext.Current.User.Identity.Name
On logging in, if the user is valid, use:
FormsAuthentication.SetAuthCookie(login.UserName, false);
rather than relying on Session to store user logged in state.
You can then check if a user is logged in by:
User.Identity.IsAuthenticated
And get their username doing:
User.Identity.Name
You can just simply use
User.Identity.Name
You can use User.Identity.Name
Please have a look at HttpContext.User Property

mulltiple account cookies on single machine

consider this, If one is user of a Web application
like :
A someone visits SomeWebSite.com as a normal User (registered)
HttpCookie cookie = new HttpCookie("LastVisit");
cookie.Value = DateTime.Now.ToString();
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
B visits SomeWebSite.com, using another account as a moderator / admin
HttpCookie cookie = new HttpCookie("LastVisit");
cookie.Value = DateTime.Now.ToString();
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
Both cookies belong to same domain, but for two different Accounts. How does browser know Which cookie belongs to which account ? if we use the following code to access it.
if (Request.Cookies["LastVisit"] != null)
{
string lastTimeUserVisited = Request.Cookies["LastVisit"].Value;
}
EDIT: It's my first time ever to work on cookies.
I do appreciate your patience
I don't quite understand the question. A single browsing session won't distinguish between the two cookies. The last cookie that the server sets replaces the previous ones. Obviously, two instances of Chrome running on two different computers don't share cookies and each send their own instance of the cookie to the server in every request.
How does browser know Which cookie
belongs to which account?
It doesn't. The cookie for the second visit overwrites the cookie for the first. If you want that to be different, you have to use different cookie names, e.g. by appending the user ID to the cookie name.
If the users are logged in using the same user account on the computer, they will be using the same set of cookies.
If they are logged in using separate user accounts, they will each have their own set of user folders and thus their own browser settings and their own set of cookies.

Revoking authentication and redirect to login page after FormsAuthentication have authenticated the user

I need to revoke an authentication cookie if the user no longer exists (or some other condition), after the forms authentication mechanism already have received the authentication cookie from the browser and have validated it. I.e. here is the use scenario:
The user have been authenticated, and granted non-expiring auth cookie.
In a few days, the user tries to access my web app again, and as the cookie is valid, the forms authentication mechanism will grant access.
Now I want to perform a second check (whatever condition I want), and decide if I want to let the user continue, or to revoke the authentication.
The question is - is there an official automated way for this? So far I have come with some possibilities, but I do not know which one is better. I can capture the Authenticate event in global.asax, check whatever I want, and to revoke I clear the cookie, and then one of these:
Redirect again to same url - this should work, as this time the forms authentication will fail, and it will redirect to logon page.
Throw some exception ??? which one to make the redirect happen w/o me specifying anything?
Somehow to get the logon page url from the config file (any ideas how/which config handler to use) and redirect directly?
Some FormsAuthentication class/method I have overlooked, which is designed for this?
Any other idea?
I don't think there is an automated way to achive this.
I think the best way would be to add a date to the auth cookie which will be the last time you checked whether the user exists.
So when a user logs-in you'll:
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // Ticket version
name, // Username associated with ticket
DateTime.Now, // Date/time issued
DateTime.Now.AddMonths(1), // Date/time to expire
true, // "true" for a persistent user cookie
DateTime.Now.ToUniversalTime(), // last time the users was checked
FormsAuthentication.FormsCookiePath);// Path cookie valid for
// Encrypt the cookie using the machine key for secure transport
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(
FormsAuthentication.FormsCookieName, // Name of auth cookie
hash); // Hashed ticket
cookie.HttpOnly = true;
// Set the cookie's expiration time to the tickets expiration time
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
//cookie.Secure = FormsAuthentication.RequireSSL;
Response.Cookies.Add(cookie);
Then everytime a user is authenicated you can check the additional date you passed to the Authentication ticket and in 10 minute intervals or less double check against the database whether the user exists.
The code might look something like this:
public void FormsAuthentication_OnAuthenticate(object sender,
FormsAuthenticationEventArgs args)
{
if (FormsAuthentication.CookiesSupported)
{
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
try
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
DateTime lastCheckedTime = DateTime.TryParse(ticket.UserData);
TimeSpan elapsed = DateTime.Now - lastCheckedTime;
if (elapsed.TotalMinutes > 10)//Get 10 from the config
{
//Check if user exists in the database.
if (CheckIfUserIsValid())
{
//Reset the last checked time
// and set the authentication cookie again
}
else
{
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
return;
}
}
}
catch (Exception e)
{
// Decrypt method failed.
}
}
}
}
You can even cache the users that have been deleted the last 10 minutes and check against that collection.
Hope that helps.
If you are rejecting the cookie for some other reason than an expired session, then I think you should redirect the user to a page that describes what they need to do in order to gain access. If logging on again is sufficient, then the logon page would suffice. It sounds, however, like there are conditions under which simply logging on again is not possible. In those cases, it would be better to redirect the user to a suitable error page that describes why they are unable to access the site and explains how to gain access again (if possible).

Categories

Resources