How do I logout of multiple asp.net applications? - asp.net

I have a main asp.net app, which is written in asp.net 1.1. Runnning underneath the application are several 2.0 apps. To completely logout a user can I just logout of the 1.1 app with FormsAuthentication.SignOut or is it more complicated than that?

What you are looking to do is called Single Sign On and Single Sign Off. There are differences based on how you have the applications set up. I will try to clarify where those differences come into play.
To implement single sign on and single sign off you need to make the cookie name, protection, and path attributes the same between all the applications.
<authentication mode="Forms">
<forms name=".cookiename"
loginUrl="~/Login.aspx"
timeout="30"
path="/" />
</authentication>
Next you need to add the machine keys and they need to be the same between all your applications.
<machineKey validationKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902"
encryptionKey="F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902F8D923AC"
validation="SHA1" />
Are you using second or third level domains for the applications? If so you will need to do a little bit more by adding the domain to the cookie:
protected void Login(string userName, string password)
{
System.Web.HttpCookie cookie = FormsAuthentication.GetAuthCookie(userName, False);
cookie.Domain = "domain1.com";
cookie.Expires = DateTime.Now.AddDays(30);
Response.AppendCookie(cookie);
}
Now to do single sign off, calling FormsAuthentication.SignOut may not be enough. The next best thing is to set the cookie expiration to a past date. This will ensure that the cookie will not be used again for authentication.
protected void Logout(string userName)
{
System.Web.HttpCookie cookie = FormsAuthentication.GetAuthCookie(userName, False);
cookie.Domain = "domain1.com";
cookie.Expires = DateTime.Now.AddDays(-1);
Response.AppendCookie(cookie);
}
I am taking into consideration you are using the same database for all the applications. If the applications use a separate database for registration and authentication, then we will need to do some more. Just let me know if this is the case. Otherwise this should work for you.

It could be easier if you are having a central session store for all your applications. You can then set the session to null in one place.

This worked for me:
In the Logout event, instead of FormsAuthentication.GetAuthCookie method use Cookies collection in Request object as below:
HttpCookie cookie = Request.Cookies.Get(otherSiteCookieName);
cookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(cookie);
Ofcourse, this requires u know the Cookie name of the site(s) you want the user to be logged out - which however won't be a problem if you are using the same cookie across all the web apps.

I prefer to use web.config
<authentication mode="Forms">
<forms domain=".tv.loc" loginUrl="~/signin" timeout="2880" name="auth" />
</authentication>

Related

FormsAuthentication.SignOut() does not expire the FormsAuthenticationTicket

First off, this is not a problem with the ASP.NET session not expiring, we clear, abandon, and delete every cookie on logout.
This is about FormsAuthentication.SignOut() not expiring the ticket when called and allowing someone who copies the content of the cookie to manually create the cookie somewhere else and still be able to acces everything that is meant to now be blocked off after the logout.
Here is the gist of our logout method:
HttpContext.Current.User = null;
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Session.Clear();
HttpContext.Current.Session.Abandon();
HttpContext.Current.Session.RemoveAll();
HttpContext.Current.Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
We also let ASP manage the creation of the ticket and the authentication via our Web.config and whatever else manages FormsAuthentication. Here is what is in the config:
<authentication mode="Forms">
<forms name="COOKIENAME" loginUrl="~/PAGE_THAT_REDIRECTS_TO_LOGIN.aspx" defaultUrl="~/PAGE_THAT_REDIRECTS_TO_LOGIN_OR_PROPER_PAGE_IF_LOGGED_IN.aspx" cookieless="UseCookies" timeout="60" />
</authentication>
Now, why is this an issue? simple, it's a security concern as if someone gets the cookie and keeps it alive, they can access whatever the user matching the cookie can, even though the user has been disconnected.
Is there is a proper way to force the FormsAuthenticationTicket to expire?
I tried decrypting it, but everything is readonly, and I also tried to create a new expired ticket and encrypting it, but it doesn't overwrite the old one.
Thanks
Versions: .NET 4.5.1, ASP.NET (not Core)
The basic problem is with Microsoft .net Core cookie Managemnt, it does not handle the lifetime of cookies correctly.
I had face this issue several times, and mostly with .Net core now.
To solve this issue we need to override their cookie management class, and implement ITicketStore interface.
https://github.com/aspnet/Security/blob/master/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs#L136
Below article can help you with detail implementation.
https://mikerussellnz.github.io/.NET-Core-Auth-Ticket-Redis/
I hope it helps.

Asp.Net MVC3 - FormsAuthentication, How to expire cookie when browser closing?

I want to expire cookie that for FormsAuthentication when browser closed.
(I want to it works like PHP session does)
Here is my Auth code that located in Model (Not controller).
Models/Auth.cs
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1,
model.UserId,
DateTime.Now,
DateTime.Now.AddDays(1),
true,
model.UserId +" "+reader["lastname"],
FormsAuthentication.FormsCookiePath);
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
if (ticket.IsPersistent)
{
cookie.Expires = ticket.Expiration;
}
HttpContext.Current.Response.Cookies.Add(cookie);
Web.config
<authentication mode="Forms">
<forms name="user" timeout="60" loginUrl="~/Auth/login" path="/"></forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
And one more questions is, there are 2 times setting cookie timeout,
in ticket,
DateTime.Now.AddDays(1),
and in authentication in Web.config file
<forms name="user" timeout="60" loginUrl="~/Auth/login" path="/"></forms>
how different they are, and which one will effect to actual expire cookie?
Anybody know, please advise me.
Thank you!
You can't expire the cookie when the browser is closed. You can, however, make the cookie non-persistent, which means it will not save the cookie and thus when you open a new browser it will have a new cookie (be aware, however, that with the way most browsers cache non-persistent cookies with tabs, the entire browser has to be closed for this to clear it out).
As for your second question, the web.config entry is used if you do not specify a timeout.
jQuery unload event can be used to detect the browser closing.
But this event is also fired when : The user clicked on a link to leave the page, or typed in a new URL in the address bar. The forward and back buttons will trigger the event.Even a page reload will first create an unload event.
Bind an event handler to the "unload" JavaScript event.
Answer the your second question, the timeout that you set in your code with override the web.config entry.

how to set the forms authentication cookie path

On the same IIS web site, I have two ASP.NET web applications called /foo and /bar. Both use forms authentication and I want users to be able to log in and out of both sites independently.
With the standard configuration for forms authentication, it seems to send a cookie path of "/" for the forms auth cookie. This means that when a user logs into /bar it logs him out of /foo which is undesirable behaviour for me.
The obvious solution seems to be this:
FormsAuthentication.RedirectFromLoginPage(username, false, Request.ApplicationPath);
This makes the forms auth cookie have the application path which allows the user to log into /foo and /bar independently :-) However there is a further and more nasty problem: If the user tries to log into /Foo (with a capital F), IIS directs them to the web application /foo, but they can never log in because the browser (chrome in this case) is case sensitive when deciding whether to send the cookie based on the cookie path.
This seems to be a common problem which every ASP.NET web app developer will face but I can't see a sensible solution for it. Please tell me i've missed something obvious?
Thanks
Andy
I assume you have already solved this issue somehow, but since I stumbled upon this question I thought I should add my few cents.
To solve the issue use different cookie names in web.config. Something like:
<authentication mode="Forms">
<forms name=".ASPXFORMSAUTH_FOO"
loginUrl="public/login.aspx" cookieless="UseCookies" slidingExpiration="true"/>
</authentication>
and
<authentication mode="Forms">
<forms name=".ASPXFORMSAUTH_BAR"
loginUrl="public/login.aspx" cookieless="UseCookies" slidingExpiration="true"/>
</authentication>
Dim ticket As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, _
pUsernameEntered, _
DateTime.Now, _
DateTime.Now.AddMinutes(60), _
True, _
pOperatorID, _
FormsAuthentication.FormsCookiePath)
' Encrypt the ticket.
Dim encTicket As String = FormsAuthentication.Encrypt(ticket)
'create a cookie with the encrypted ticket
Dim authenticationCookie As New HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
'only create a persistent cookie if ticket persistent is checked
If (ticket.IsPersistent) Then
'give the cookie an expiration date outside of the forms authentication encrypted ticket
authenticationCookie.Expires = ticket.Expiration
End If
'save the cookie
HttpContext.Current.Request.Cookies.Remove(".cookiename")
Response.Cookies.Add(authenticationCookie)
In cookiename you can set you cookie name.
and in AddMinutes you can set your minutes values currently it is 60.

Single Sign-on SignOut problem : FormsAuthentication.SignOut() is not working

I used the Single Sign-on demo from: http://www.codeproject.com/KB/aspnet/SingleSignon.aspx
And I add a SignOut function for this demo, but found a problem:
when I set the cookie.Domain, FormsAuthentication.SignOut() is not working and the cookie can not be cleared.
If the cookie has not been set the cookie.Domain, FormsAuthentication.SignOut() works.
I used C# asp.net.
And could anybody tell me some simple and practical Single Sign-On and Single Sign-Off solutions using asp.net ?
In case you are using the authentication for the same domain and subdomain, try adding the domain name in the web.config instead of adding the domain through code. you will no have to code anything if you use this web.config entry
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" domain="abc.com"/>
</authentication>
This entry tells the asp.net engine that the authentication cookie will be used for all subdomains of abc.com . Try using this and see if it works.
This worked for me:
In the Logout event/ method of each site, use Cookies collection in Request object & delete the relevant cookies as below:
enter code hereHttpCookie cookie = Request.Cookies.Get(".CommonCookieName");
cookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(cookie);
If all the sites in SSO use same cookie, then this is simple as described above.
If few or each site participating in SSO use their own cookie/ user name for same subject (person), then u need to remove all the cookies. (perhaps establish a central location with just the mapping of the usernames & cookie names in each site in SSO collection of sites.
This works for me
public virtual ActionResult LogOff()
{
FormsAuthentication.SignOut();
foreach (var cookie in Request.Cookies.AllKeys)
{
Request.Cookies.Remove(cookie);
}
foreach (var cookie in Response.Cookies.AllKeys)
{
Response.Cookies.Remove(cookie);
}
return RedirectToAction(MVC.Home.Index());
}

sync cookies and sessions in different subdomains (asp.net)

I am building a site in asp.net and have multiple subdomains. For example,
one.cookies.com
two.cookies.com
I want my users to be able to login at either subdomain and be logged in for both websites. In addition, I'd like the sessions and cookies to be in sync. So far I haven't found a reliable way to do this.
If you want to sync the ASP.NET session and you aren't using forms authentication (for example, your site has no login), try adding the following code to your Globals.asax file. This worked like a champ for me and saved me some serious grief.
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
/// only apply session cookie persistence to requests requiring session information
#region session cookie
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState )
{
/// Ensure ASP.NET Session Cookies are accessible throughout the subdomains.
if (Request.Cookies["ASP.NET_SessionId"] != null && Session != null && Session.SessionID != null)
{
Response.Cookies["ASP.NET_SessionId"].Value = Session.SessionID;
Response.Cookies["ASP.NET_SessionId"].Domain = ".know24.net"; // the full stop prefix denotes all sub domains
Response.Cookies["ASP.NET_SessionId"].Path = "/"; //default session cookie path root
}
}
#endregion
}
I found this originally posted here:
http://www.know24.net/blog/ASPNET+Session+State+Cookies+And+Subdomains.aspx
When you create the cookie you can set the domain:
HttpCookie cookie = new HttpCookie("name", "value");
cookie.Domain = "cookies.com";
This will allow your cookie to be accessible from all subdomains of cookies.com.
If you are using FormsAuthentication then you can set the domain for the auth cookie in web.config:
<forms name=".ASPXAUTH"
loginUrl="login.aspx"
defaultUrl="default.aspx"
protection="All"
timeout="30"
path="/"
requireSSL="false"
domain="cookies.com">
</forms>
Remember that for the single sign-on to work on multiple subdomains your ASP.NET applications must share the same machine keys as explained in this CodeProject article.
Sharing sessions between different subdomains (different worker processes) is more difficult because sessions are constrained to an application and you will have to implement a custom session synchronization mechanism.
Yes, you need to use ".cookies.com" not "cookies.com"
I beleive make the cookie for http://cookies.com. (No subdomain or www listed)

Resources