URL Rewrite for subdomain fails with identityserver3 - asp.net

We have a wild card domain hosted on azure. I've setup up subdomain.domain.com to rewrite to domain.com/subdomain. It all works fine.
However when I login to our identity server, once the login process is completed and I am redirected back to subdomain.domain.com it seems like the authentication token is lost.
I can't see how this can be possible. This issue happens with all our identity providers (google, Facebook, Microsoft live)
If I change the setup to use domain.com/subdomain then everything works as expected

The main issue is what type of cookie your identity server places,
It looks like your server places and domain specific cookie, and not a wildcard one.
Cookie domains
Common issue with the cookie for the authentication is the domain for the cookie. Similarly to the paths of the cookies, if the cookies are created on two different subdomains, then the cookie will only be accessible on the domain where it was created. For instance, your main application may be on www.domain.com, but you have Telligent Evolution running on cs.domain.com. If you create the cookie on www.domain.com, the browser will only send it to that domain, and it won’t be passed along when they navigate over to cs.domain.com.
The cookie can be carried over by setting the domain to “.domain.com”. Cookies don’t use the common “*” wild card. Simply use “.domain.com”. With this entry, the browser will not to pass the cookie when it goes over to cs.domain.com as well.
Like the path, the domain can be specified in either the web.config or through code. When setting the web.config file, it will only check for the authorization cookie. You must have this set for the site to correctly recognize the new domain level cookie:
<authentication mode="Forms">
<forms name=".CommunityServer" ... domain=".domain.com" />
</authentication>
The "domain" name is ignored by the FormsAuthentication.SetAuthCookie method, so you must manually set it on your login page when creating the AuthCookie. For example:
HttpCookie cookie = FormsAuthentication.GetAuthCookie(username, true);
cookie.Domain = ".domain.com";
Response.Cookies.Add(cookie);

Related

ASP.NET redirects to cookieless URL and loops on form login even though cookieless is set to false

I have a very strange behaviour on my production server that only happens a few times during a week. On a form login POST a redirect is sent to what looks like a cookieless URL like:
"/(F(kD5qGnK-0b5L80VYgScenFuCnjQsLR67HhXq-BWXS1hL45hhqL8AiLlEyB-9CuJgutiyXzN42w8Bo_cm2o73GFWP_fuQ1AtPfXSaB7odZYAOBnuNW3Yy873fQDpRzYgOVo3Ee48gaCbS7FUIyOBA3CksCTZ3N6YCZ7pcZylZEo01))/SiteSpecificPath/CMS/edit/"
What normally happens is a redirect to just "/SiteSpecificPath/CMS/edit/".
This in turn leads to a redirect loop going back to the login.aspx page and continuing like that.
I don't want to use cookieless so the question is how this is triggered? And is there a way to disable this behaviour? I have looked through all levels of config files and cookieless is set to false on all places.
The site is an EPiServer CMS site, but in this case it seems to be related to a normal asp.net forms login procedure that for some reason triggers a switch to cookieless URLs.
I have found some references about cookieless triggering a redirect loop, but in my case the strange thing is why it even starts using cookieless URLs in the first place.
I have also done debugging using advanced logging to see all headers sent from the browser, but I don't see anything strange there. Cookies are sent as normal, including the ASP.NET session cookie.
EDIT: This is not an access problem. A given user can normally login, but sometimes this redirect loop is entered.
Some details: IIS7 on Windows Server 2008 R2, EPiServer 6 R2, ASP.NET 4
Possibly the user doesn't has access to the redirect URL and this is why it redirects everytime to login page and continues like that.
Firstly check if the user is authorized to access the page in the redirect url.If the user isn't authorized, redirect to a page that the user can access Or update the access rights for the user.
I don't want to use cookieless so the question is how this is triggered
When using FormsAuthentication, Check your Settings for same in web.config. As seen below this has a property cookieless which can have options as AutoDetect,
UseCookies, UseUri, and UseDeviceProfile.
<authentication mode="Forms">
<!-- Detailed configuration options -->
<forms name="MyForm"
loginUrl="Login.aspx"
timeout="30"
cookieless="UseCookies"
... />
</authentication>
So, in your case the value for cookieless seems to be either : UseUri OR AutoDetect, although UseDeviceProfile is possible too.
UseUri:If this configuration option is selected, cookies will not be used for
authentication. Instead, the runtime encodes the forms authentication ticket
into the request URL
AutoDetect:Results in the use of cookies if the client browser supports cookies. Otherwise, URL encoding of the ticket will be used.
UseDeviceProfile :: Results in the use of cookies or URL encoding based on a device profile configuration stored on the web server. These profiles are stored in .browser files in the c:[WinDir]\Microsoft.NET\Framework[Version]\CONFIG\Browsers directory.
Since you don't want to use cookieless, set the value for cookieless to UseCookies.
NOTE: When using the setting cookieless="UseCookies" , requires the client browser to support cookies. If the browser does not support
cookies, forms authentication will simply not work. As
it will never receive a valid authentication cookie from the browser, ASP.NET
redirects back to the login page over and over again, and you end up in an
endless loop of presented login pages

Sitecore with requireSSL for cookies

Our Sitecore 6.6.0 (rev. 120918) based website can work over http as well as https. We also have a security requirement of making all the cookies to transfer over SSL regardless of whether the website is accessed via http.
We have achieved this requirement by using the requireSSL property in the web.config as described here: How can I set the Secure flag on an ASP.NET Session Cookie?
With this change, our public website works fine and when analyzed in Firebug, we can see that all cookies are "secure" even when the website is accessed via http.
But the problem is when I try to login to the sitecore admin portal via http, it throws the error The application is configured to issue secure cookies. These cookies require the browser to issue the request over SSL (https protocol). However, the current request is not over SSL. The only way I can access the sitecore admin portal is via https. Even with https, it gives some weird issues. After some time of use, it says that lot of admin users are logged in and I have to kick some out to get in. I also can't access the admin portal remotely.
Why is it that the public website works with SSL cookies, but the sitecore admin portal has issues with SSL cookies. Could it be and incompatible configuration in our site?
I think the problem will be that you have set <httpCookies requireSSL="true" /> which will set the cookies to secure, but also have to set the forms authentication:
<system.web>
<forms requireSSL="true">
/* forms content */
</forms>
</system.web>
As this would override the cookie setting. The problem is having that set on the forms section requires that the login happen over https not http. On your public website, you will only see this issue if there is a login form.
To fix this you will either have to enable SSL for your authoring system (which is recommended anyway) or put up with not using secure cookies.
MSDN: FormsAuthentication.RequireSSL Property
Based on the error message I'd guess the login is trying to set a cookie with the secure attribute when the connection isn't secure. This would of course succeed if the request was secure already.
As a workaround you may be able to use IIS Rewrite to redirect the request to /sitecore onto SSL prior to any cookies being set since I assume you do want all requests on SSL for content management.
I might also be totally incorrect here :)

Forms Authentication - Redirect Back to Original Domain

Example:
Application = https://test2.mytest.com/MyApplication/Download.aspx
The application has forms authentication enabled in the web.config:
<authentication mode="Forms">
<forms loginUrl="https://test.mytest.com/Login/" name=".ASPXAUTH"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
When accessing the application it correctly redirect to the login page:
https://test.mytest.com/Login/?ReturnUrl=%2fMyApplication%2fDownload.aspx
However, after successfully logging in it goes to:
https://test.mytest.com/MyApplication/Download.aspx
instead of
https://test2.mytest.com/MyApplication/Download.aspx
It is using the sub-domain of where the login application is (test.mytest.com), not the sub-domain of the original request (test2.mytest.com).
Is there anyway to have forms authentication redirect back to the original requesting sub-domain instead of the sub-domain that the login app is on?
Any help on this would be greatly appreciated.
Yes it is certainly possible, but you'll need to make changes on both the authenticating sub domain and the sub domain requiring authentication.
The sub domain requiring authentication.
The issue you're having is that when an anonymous user attempts to access a secured resource ASP.NET forms authentication redirects them to the login page and appends the original requested resource in the "ReturnURL" query string but this ReturnURL parameter is a relative URL.
So to get this to work in the way you want, you'll need to manipulate the ReturnURL parameter to indicate in some way that the return is to a different site.
One way to do this is to manipulate the ReturnURL using an HttpHandler to hook into the PostAuthenticateRequest, as detailed in this article, Forms Authentication With Absolute Return URLs.
The authenticating sub domain
To enable redirection to the calling subdomain you'll need to set the enableCrossAppRedirects attribute to "true" in the forms section of the web.config to allow redirection to a URL in another web application. Be aware of the implications of this though as it leaves you open to open redirection attacks.
An alternative and more secure approach to just setting the sub domain address directly on the ReturnURL (helping prevent open redirection attacks) is to modify the ReturnURL to contain a known parameter in the querystring and then modify the Application_EndRequest in the global.asax.cs of the authenticating subdomian as mentioned here and here to rewrite the Response.RedirectLocation.

Authentication cookie with subdomains

i have an asp.net website http://www.site.com. This web app is also running on http://subdomain1.site.com and http://subdomain2.site.com. Now i want to set authentication cookie in such a way that http://site.comand http://www.site.comshare authentication cookie but it should not be shared by http://subdomain1.site.com. similarly, http://www.domain1.site.com and http://domain1.site.com should share cookie but it should not be shared by http://domain2.site.com or http://www.domain2.site.com. How can i handle this with asp.net?
By default, cookies are associated with a specific domain. For example, if your site is www.contoso.com, the cookies you write are sent to the server when users request any page from that site. (This might not include cookies with a specific path value.) If your site has subdomains—for example, contoso.com, sales.contoso.com, and support.contoso.com—then you can associate cookies with a specific subdomain.
Response.Cookies["domain"].Domain = "support.contoso.com";
Normally a cookie set on contoso.com will be accessed by all subdomain. but if you want to limit sub domain for the cookie you should manually set domain property for each domain you want them to access.
Regards.
I ended up using different cookie names on different domains as described in this article

Asp.net forms authentication and multiple domains

I have two domains, domain1.com and domain2.com pointing at the same asp.net website which uses asp.net build in form authentication. The problem is that even if the domains point to the same website the user only get authenticated for one domain at a time. So if he uses www.domain1.com first and then visits www.domain2.com it's the same website in the back but he only is authenticated for www.domain1.com. The same thing happens if he uses www and not www when visiting the sites.
This is what I use to login:
FormsAuthentication.RedirectFromLoginPage(username, cookie.Checked);
To check login:
User.Identity.IsAuthenticated
How can I make the user gets authenticated for all domains that points to the same website?
What you're after is a Single Sign-on solution.
As ASP.NET authentication is at it's heart generally cookie based, there are two things to look at:
Set your cookies correctly.
Bounce your users to the alternative domain during signup.
Looking at both of these in more depth:
1. Setting cookies correctly
You need to ensure that ASP.NET is writing the authentication ticket cookies to the root domain, rather than the explicit domain this is done using the domain attribute of the forms element:
<forms
name="name"
loginUrl="URL"
defaultUrl="URL"
domain=".example.com">
</forms>
You should set your domain to ".example.com" - note the leading period - this is the key. This way requests to example.com and www.example.com will both read the cookie correctly, and authenticate the user.
2. Bounce users to the alternative domain
What we have implemented on a few sites that use a single sign on is a round trip login process. The user authenticates on the first domain, we encrypt the login details, and redirect them to a known page on the second domain, log them in there, and then redirect back to the original server.
This client side redirection is important - cookies are only written when there is a response back to the client, and the browser has to visit the second domain to actually see the cookies.
Other details to consider in this sort of set-up:
You probably want to have a timeout on the encrypted sign-in details - so that recalling that URL from the browser history doesn't automatically log the user in.
If the domains are on different servers, you will need to ensure that either the machine keys are configured the same, so that you can encrypt and decrypt the details correctly, or use some other shared key.
You will probably want to have a mechanism in place to recall the users ReturnUrl from the original server so that you can send them back to the correct place.
You could also take a look at "Forms Authentication Across Applications"
You could try setting cookieless="true".
You should read Explained: Forms Authentication on MSDN. They cover Cross-Domain Authentication.

Resources