Form authentication across multiple applications - asp.net

We are trying to use authentication between two applications on our PC's (Windows 7, IIS 7.5) and eveything goes fine. But the problem is when we try to publish these sites (Windows web server 2008, IIS 7.0) the cross authentication didn't work!!
After long invistigation we found that the error occured in the following code which is on the second site:
Dim formsCookie As HttpCookie = Request.Cookies(FormsAuthentication.FormsCookieName)
If (formsCookie IsNot Nothing) Then
Else
' always null
We tried to check the pathes like this in code behind :
Dim ticket As New FormsAuthenticationTicket(1, smsProfile, DateTime.Now, _
DateTime.Now.AddDays(1), True, AdminSessions.UserObj.Pid, _
FormsAuthentication.FormsCookiePath)
Dim hash As String = FormsAuthentication.Encrypt(ticket)
Dim cookie As New HttpCookie(
FormsAuthentication.FormsCookieName,
hash)
If (ticket.IsPersistent) Then
cookie.Expires = ticket.Expiration
End If
Response.Cookies.Add(cookie)
Response.Redirect(smsPortal)
in the web.config:
<authentication mode="Forms">
<forms name=".ASPXFORMSAUTH" enableCrossAppRedirects="true" domain="mydomain.com.jo" loginUrl="http://..." protection="All" path="/"/>
</authentication>
Kindly advice us what is the difference between IIS in local PC and the Server.
Thanks.

It is highly likely that the browser is not sending the authentication cookie from the first site to the second site. Check the cookie path and the domain. Both sites must be on the same domain, and the cookie path must be set to a common root.
See this link for more details:
Cookie Domains and Paths
To aid in troubleshooting, use a utility such as Fiddler or Firebug to view the cookies being sent in the request, and verify that the authentication cookie set by site 1 (where the user logged in) is also being sent to site 2.
If the sites aren't on the same server, also check if they are using the same machineKey configuration.

Related

ASP.NET Forms Authentication Across Applications Issue

This has been the bane of my existence for the better part of a week.
I have four existing webforms applications that utilize forms authentication. The URL for each is mydomain/app1/, mydomain/app2/, etc. I have been tasked with creating a new application that will function as a single sign-on application with the URL mydomain/ssoapp. Once a user logs in, it basically compiles everything from the pre-existing apps that the user has access to, so our users don't have to go out and log into each of them separately. But the old applications need to function as they currently do.
The important part of my web.config is as follows:
<authentication mode="Forms" >
<forms loginUrl="frmLogin.aspx?Type=login" name="sqlAuthCookie" protection="All" path="/" domain="mydomain"
timeout="60" cookieless="UseCookies" enableCrossAppRedirects="true" />
</authentication>
<machineKey validation="SHA1" decryption="AES" decryptionKey="mykey" validationKey="myvalkey"/>
Simply adding this to the web.config for all of the applications worked like a charm....for three of them.
In the SSO application I'm creating a formsauthenticationticket, cookie, and adding that to the response with the following code. Each of the four pre-existing applications uses this same code as well:
Dim lTicket As New FormsAuthenticationTicket( _
1, _
pstrUserId.ToString, _
System.DateTime.Now, _
System.DateTime.Now.AddMinutes(60), _
True, _
pstrUserId.ToString, _
FormsAuthentication.FormsCookiePath)
' Encrypt the ticket.
Dim lencTicket As String = FormsAuthentication.Encrypt(lTicket)
' Create the cookie and add to response
Dim cookie As HttpCookie = New HttpCookie(FormsAuthentication.FormsCookieName, lencTicket)
cookie.Domain = ".mydomain.gov"
pobjResponse.SetCookie(cookie)
pobjResponse.Cookies.Add(cookie)
'Cleanup
lencTicket = Nothing
lTicket = Nothing
In chrome debugger for the SSO application, I log in and the cookie is created with the correct information.
I can click on my menu list, which uses a response.redirect to go out to the other applications. For the 3 working applications, I bypass the login screen, go directly to the form I need, and the cookie is unchanged
For the problem child application, I can still see the cookie however I am redirected back to the login screen.
If I login from this point, a new cookie is created, with the same name as the preexisting one, however the domain has the "www" prefix on it
Other useful information (maybe):
I've ensured that all machinekey, decryption key, validation method, etc match across applications
My domain is in the format of sub1.mid1.gov . I've tried every combination of the format for this in the cookie assignment and web.config. Both with and without the preceding dot.
I've removed httpRuntime from the web.config as some others had mentioned this causes issues.
There are no errors in the IIS logs
All applications are running under the same apppool currently
Currently I'm contemplating taking some vacation time so I don't feel bad about crying in the corner on my employers dime. I'm sure it's something ridiculously simple, but I appreciate any help in the matter. Thanks!

FormsAuthentication and Session cookie are lost in Firefox

Hope someone can help me with this cause this problem has been bugging me for some time now.
I'm building a webshop and i'm integrating with a payment system hosted by a third party.
I have people review their order and when they click to proceed to entering in their credit card information i send them off through a secure connection to the payment system hosted on a different server, providing them with an "OK"-URL for sending them back to my site so i can close the order and do some other stuff, after a successful payment.
The problem is in Firefox when the remote server redirects back to my server the session id is lost and the forms authentication cookie is a completely different one, resulting in the user being logged out. This is not the case in IE, Safari and Chrome.
Take from Fiddler2 before redirecting to remote host
Request sent 342 bytes of Cookie data:
ASP.NET_SessionId=uusldflsxdecn0cfkoaw11tx;
.ASPXAUTH=90109DFD47272DDB02905800582D[....]1878E319DED0DD63BBCA07C1114CD02EA32E7FE3C28BB3ECA07D3EF2131E7425AB6AF4D48777FBE9F965675CA9D0A8CF66AF4433F2CE045ADB419317F9C6F04D32669EF5EB87135B9949EC4462F2826BB6B
After remote host redirects back to my server
Request sent 298 bytes of Cookie data:
.ASPXAUTH=A73EE1BE818E1FE934F0AD8D48078E26646318DA24886CAE9[...]23AD63D679D0D838E746DE6357DBE0D3EA32A634873A62F399E1033138648314E83F1282A1949D64F4FC833948F1D3ABA5D997D8CABE3C6CA04256404A25FFC8C3D427A7640B488B01532314EE68
This seems really strange to me, and i haven't been able to find a way around this. My process for doing things works perfectly in IE, Safari and Chrome..
Is this a problem on the remote server? Is there something i'm doing wrong?
Is there a way of reconstructing the session somehow?
From web.config:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="1440"/>
</authentication>
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, ..." connectionStringName="DefaultConnection"/>
</providers>
</sessionState>
I still don't know why the above problem occurs, but after sleeping on it I figured out a pretty basic solution. I simply save the cookie values in my database before redirecting people to the remote host, and upon return i check the cookie values in the request and if there's a discrepancy i restore them with the ones from the database.
If the session key is lost upon return though, i have to make one redirect with the restored session cookies before accessing anything put in the session, for which i just use a RedirectToAction call, to another action in the same controller.
private void SaveCookie(int orderId)
{
var sessionCookie = Request.Cookies.Get("ASP.NET_SessionId");
var authCookie = Request.Cookies.Get(".ASPXAUTH");
var ci = new CookieInformation
{
OrderId = orderId,
SessionCookie = sessionCookie.Value,
AuthCookie = authCookie.Value
};
Database.SetCookieInformation(ci);
Logger.Info("Saved sessionId: " + sessionCookie.Value + " auth: " + authCookie.Value, this.ToString());
}
And after returning:
private void RestoreCookies(int orderId)
{
var reqSessionCookie = Request.Cookies.Get("ASP.NET_SessionId");
var reqAuthCookie = Request.Cookies.Get(".ASPXAUTH");
var savedCookie = Database.GetCookieInformation(orderId);
if (reqSessionCookie.Value != savedCookie.SessionCookie || reqAuthCookie.Value != savedCookie.AuthCookie)
{
Response.Cookies.Clear();
Response.Cookies.Set(new HttpCookie("ASP.NET_SessionId", savedCookie.SessionCookie));
Response.Cookies.Set(new HttpCookie(".ASPXAUTH", savedCookie.AuthCookie));
}
}

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.

asp.net forms authentication timing out after 1 minute

I'm using ASP.NET MVC 3 with the Authorize attribute, but it keeps kicking me to the logon page after 1 minute, but even though my expiration is set to a very high value, it times out quickly. I check the cookie in my browser and its still there and not set to expire until about a month later, and it's set to be persistent, so I'm not sure why it keeps booting me. It only happens on my published location, locally it works just fine.
var ticket = new FormsAuthenticationTicket(username, true, 500000);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
cookie.Expires = ticket.Expiration;
Response.Cookies.Add(cookie);
web.config:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="7200" slidingExpiration="false"/>
</authentication>
Chances are the worker process is recycled meantime, Where do you store the sessions?
Making your sessions stored out of process may helps.

How do I logout of multiple asp.net applications?

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>

Resources