Sharing a cookie between two websites on the same domain - asp.net

Here's the situation:
Website A, ASP.NET MVC 4 web application. Domain: http://a.example.com
Website B, ASP.NET MVC 4 web applicaiton. Domain: http://b.example.com
I'm trying to share a cookie (forms authentication) between the websites.
I'm not using Forms Authentication per-se. I'm using the built-in methods (Encrypt, Decrypt, etc), but I'm setting my own custom cookie.
When I set the cookie on one of the websites, the other ones sees the cookie, but can't decrypt it. The error is the generic "Error occurred during a cryptographic operation".
What I've ensured:
The cookie has the domain set to "example.com" (which means subdomains can access. Proof is the other website can "see" the cookie).
Both websites share the same machine key. The web.config for both has the same value for the decryptionKey and validationKey.
The forms authentication ticket version and cookie name are the same across both websites.
The path is set to "/".
I've done this before and it works fine, but in that scenario both applications were sharing the same code base.
In this instance, they are separate applications. This is because i am prototyping a solution where two platform-independent applications on the same top level domain can share a authentication cookie.
Can anyone tell me what i's missing, or provide an alternative solution.
I've read all the related questions, but the answer is usually 2) above.

When you create a new ASP.NET 4.5 (e.g ASP.NET MVC 4) application, the following line is added to the web.config:
<httpRuntime targetFramework="4.5" />
This was not present in my other application, possibly because my other application was an ASP.NET 3.5 application which was upgraded to 4.5.
Removing that line in the new ASP.NET web application fixed the problem.
I think this is due to the compatability mode value:
http://msdn.microsoft.com/en-us/library/system.web.configuration.machinekeysection.compatibilitymode.aspx
Framework45. Cryptographic enhancements for ASP.NET 4.5 are in effect. This is the default value if the application Web.config file has the targetFramework attribute of the httpRuntime element set to "4.5".
Not sure i get how removing that line solved the problem. I assume application one has a different compatability mode, since it didn't have that httpRuntime element.

The Best way to handle this is to make machinekey decryption fall back to Framework20SP2
From this article : http://msdn.microsoft.com/en-us/library/system.web.configuration.machinekeysection.compatibilitymode.aspx
Just add that attribute to machinekey in your .net 4.5 application
<machineKey validationKey="" decryptionKey="" validation="SHA1" compatibilityMode="Framework20SP2" />
you won't need to remove targetFramework="4.5" from httpruntime now.

Related

ASP.NET auth using Windows Authentication for intranet

I know this has been asked a lot, but I have not been able to find a working solution.
I'm trying to create an intranet website where I want to use Windows Authentication. But for some reason I can't get authentication to work.
I've searched far and wide on MSDN, Stack Overflow, blogs etc. and tried the proposed solutions - to no avail.
Here's what I'm using:
IIS 10.0.14393.0 (real IIS, not express)
Windows 10 (1607)
.NET Framework 4.6.1
ASP.NET MVC 5.2.3
In Visual Studio I created a new empty ASP.NET Web Application and put a checkmark in MVC. Then I added a very simple (Hello World) controller, model and view.
Finally I added the following (which many people claim to be the right solution) to web.config in the system.web section:
<authentication mode="Windows"/>
<authorization>
<allow users="DOMAIN\USER"/>
<deny users="*"/>
</authorization>
In IIS I created a new website, pointed it to the web application folder, and set up a host name which I added to "hosts" file.
Then I enabled the "Windows Authentication" feature under Authentication section.
In Internet Explorer (or Firefox or Chrome for that matter) I navigate to the website, using the route to the controller, and I'm then prompted for credentials. I enter credentials for the domain user, but I'm denied access.
Some people claim that "Anonymous Authentication" in IIS should also be enabled, but for me this doesn't help at all. Same problem.
Also, some people claim that it helps to go to "Providers" for "Windows Authentication" and reorder them to: NTLM, Negotiate. Doesn't change a thing for me.
Then I try to change authorization in web.config to just:
<allow users="*"/>
Doesn't help either.
It's like the auth-thing doesn't talk to AD at all.
Anyone know how to set this up correctly given the described scenario?
UPDATE (dec 8, 2016):
I found a pluralsight video (referenced from the asp.net/mvc website) by Scott Allen, where he explains the different authentication options for MVC5, and when it comes to doing an intranet site with Windows Authentication, it turns out it should be done pretty much like I've described in this question. Only thing is, when I try it out (I used the VS template for MVC and chose Windows Authentication), it only works in IISExpress - not in real IIS (even on same machine and both IISExpress and IIS setup to use Windows Authentication and not allow anonymous). So very frustrating.
You should not use <authorization> tag in ASP.Net MVC. It is meant for ASP.Net Web Form which is based on paths, whereas ASP.Net MVC works with Controllers, Actions and Routes.
In ASP.Net MVC, there are few ways to authenticate user via AD. I personally like to use use OWIN Middleware.
It has few pieces, so I created a sample project in GitHub AspNetMvcActiveDirectoryOwin. You can fork it, and test it right away.
The following three are the main classes -
AccountController
ActiveDirectoryService
OwinAuthenticationService

Windows Authentication for ASP.NET MVC 4 - how it works, how to test it

I have never used Windows Authentication for ASP.NET MVC web applications before, but Forms Authentication. Recently, I have had an ASP.NET MVC 4 web application that requires a Windows Authentication implementation for users who are granted to log in my company web server. So, I have some questions regarding Windows Authentication. I am using Visual Studio 2012.
How does Windows Authentication work?
How do I implement Windows Authentication correctly in the web.config file?
How do I test if the Windows Authentication really works for my ASP.NET MVC 4 web site? In other words, how do I test it on my local development PC with local IIS (version 8), and on my company real web server with IIS version 7?
For IIS 8.5 and MVC 4:
How does Windows Authentication work?
In this mode, User.Identity (as in HttpContext.Current.User.Identity) is populated by the underlying web server. This might be IIS Express in the link from #R Kumar demonstrated, or full blown IIS as in the video by #Thomas Benz.
Specifically, User.Identity is a WindowsIdentity object. E.g. the following cast will work:
WindowsIdentity clientId = (WindowsIdentity)HttpContext.Current.User.Identity;
How do I implement Windows Authentication correctly in the web.config file?
<system.web>
<authentication mode="Windows" />
...
How do I test if the Windows Authentication really works for my ASP.NET MVC 4 web site? In other words, how do I test it on my local development PC with local IIS (version 8), and on my company real web server with IIS version 7?
First, change the ASP.NET authorization to exclude the current user. E.g.
<system.web>
<authentication mode="Windows" />
<authorization>
<allow users="yourdomain\someotheruser" />
<deny users="*" />
</authorization>
Second, enable Windows Authentication for your site using IIS Manager. It's under the 'Authentication' feature. And disable anonymous authentication.
Note that older explanation will suggest you make changes under element of your site's web.config. However, recent IIS implementations prevent this for security reasons.
Three, point your browser at the webpage. The browser should ask you to provide credentials, because the current user is not allowed access to the website. Provide the ones that are authorized for the site, and your MVC code should run.
Four, check the user identity. E.g.
WindowsIdentity clientId = (WindowsIdentity)HttpContext.Current.User.Identity;
I have done this with ASP.NET MVC 1.0. That was a relatively long time ago. I remember the IIS settings being confusing. I just did some checking, and it does not look like things have changed much to ASP.NET MVC 4.0 as far as attributes on the controllers.
For your questions:
How does it work? The following references pretty much sum things up pretty well. Authenticating Users with Windows Authentication (C#)
is NOT exactly right for ASP.NET MVC 4.0, but it has some background.
How to Create an Intranet Site Using ASP.NET MVC is for ASP.NET MVC 3.0.
I am too new to post more than two links, so you will have to search MSDN for "AuthorizeAttribute Class" for .NET Framework 4.
What settings for web.config? - I just remember changing one element, "authentication mode".
As far as testing, my Windows OS versions matched better, and my development machine was on the same Windows domain. But if I remember correctly, this just worked. YMMV, but one thing I do remember considering was implementing my own authorization. Maybe that is an avenue for your case, to roll your own, and then switch to Windows authentication in production. But I would suggest a couple of test iterations with a test server if you can set one up on the company domain.
I found out a helpful video that was very useful to me by showing step by step to implement and test Windows authentication for an ASP.NET MVC web site. So, I close this question.
Video from a very kind poster:
How to implement windows authentication in ASP.NET MVC 3 ( Model view controller) application?

ASP.Net membership login issue

I am trying to run two web application using the same ASP.NET membership provider database that comes with MVC3. So two web app runs side by side and they both has the same connection to the same membership databse. The problem now is, I can only login at one app and get automatically log out at the other. However, the feature I want is, if I log into either one, I get automatically log into the other.
I was wondering what the trick is to enable this feature.
thanks a lot
If you are using Forms Authentication users are tracked with cookies. Cookies are by default restricted only to the application that emitted them. And because of this the other application cannot see the authentication cookie created by the first. So for example if you have the two applications hosted respectively on foo.example.com and bar.example.com you could set the domain property of the cookie in web.config of both applications to example.com:
<forms
loginUrl="/login/index.mcp"
requireSSL="true"
protection="All"
timeout="120"
domain="example.com"
/>
This way the cookie will be shared among those two applications and you will be able to achieve Single Sign On.
Finanlly I fixed it.
My application runs under the same domain so domain is not a problem (But Thank you very much, Darin).
The problem is:
IIS by default generate differnt machine key for differnt web application. So I have to specify the same machine key in web.config explicitly~!

protecting non .aspx pages with Asp.net Membership provider

I'm currently using the asp.net membership provider (with logins stored in db) to protect certain pages of my site. However, I also have non .aspx resources I wish to protect - word docs, excel spreadsheets, pdfs, etc. Is this even possible? If so how would I go about doing this?
thanks!
If you are running IIS 7 under the integrated pipeline (the default setup), all requests go through IIS. This means you have to do nothing other than setup your web.config. You'll need to do one little thing though, put the following attribute on the modules node under system.webServer:
<modules runAllManagedModulesForAllRequests="true" />
This ensures that the forms authentication modules run for your static content.

Single Sign On with Forms Authentication

I am trying to set up Single sign on for 2 websites that reside on the same domain
e.g.
http://mydomain (top level site that contains a forms-auth login page)
http://mydomain/admin (seperately developed website residing in a Virtual Application within the parent website)
Have read a few articles on Single Sign on
e.g.
http://www.codeproject.com/KB/aspnet/SingleSignon.aspx
http://msdn.microsoft.com/en-us/library/dd577079.aspx
And they seem to suggest it is just a case of having the same machinekey section in each web.config so that the cookie encryption and decryption is the same for each application
I have set this up and I never get prompted for credentials in the sub-website (the virtual application)
I always get prompted in the parent site.
In addition to having the same machinekey I've also tried adding the same <authentication> and <authorisation> elements
Any idea what I could be missing?
Your forms section of web.config needs to be the same as well.
Quote from - Forms Authentication Across Applications
To configure forms authentication across applications, you set attributes of the forms and machineKey sections of the Web.config file to the same values for all applications that are participating in shared forms authentication.
The following example shows the
Authentication section of a Web.config
file. Unless otherwise noted, the
name, protection, path, validationKey,
validation, decryptionKey, and
decryption attributes must be
identical across all applications.
Similarly, the encryption and
validation key values and the
encryption scheme and validation
scheme used for authentication tickets
(cookie data) must be the same. If the
settings do not match, authentication
tickets cannot be shared.
I had used <clear/> on the httpModules section, as there were items in the parent that did not exist in the bin dir for the child (/admin)
In doing so (using <clear/> that is ) I had inadvertently cleared the FormsAuthentication module specified in the web.config in
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG
so i needed to re-add those explicitly to the child (/admin) config
Try configuring the httpCookies section in the web.config of both applications to use the same domain. That way when you log-in to one app the FormsAuthentication cookie you get will be visible to the other application.
You need to have the same authentication elements in the web.config. In the contained forms element, make sure you give each application the same value for the name attribute. For the loginUrl attribute, I use a relative path and use the same logon page for all of the applications (e.g. loginUrl="/MainApp/login.aspx").
Also, are you creating the authentication ticket manually?
There is a breaking change in ASP.NET 4.5's token generation
If you're mixing ASP.NET 4.5 apps with apps targeting earlier versions, you will need to ensure compatible tokens are used everywhere. Add this attribute to the <machineKey> on any site targeting .NET 4.5 or higher:
<system.web>
<machineKey compatibilityMode="Framework20SP2" />
</system.web>
See this answer for more details. Special thanks to this comment which pointed me in the right direction.

Resources