STS Authentication - MVC Site - asp.net-mvc

I have two servers: STS and Web. On the STS server, I call:
FormsService.SignIn(model.UserName, false);
The next line, I check:
User.Identity.IsAuthenticated
This is set to TRUE. Then I redirect back to my Web server and in the controller I hit, I check:
User.Identity.IsAuthenticated
This is set to FALSE.
What could cause this?
UPDATE: I also just tried moving the STS web site to the Web server. I get the same error/issue
UPDATE: I forgot to mention that our DEV server works just fine. The configuration there is identical (except for the server name and cert thumbprints). The only thing different between these two servers is that one (DEV) is using a self-signed cert and is inside our firewall. The other (QA) is using an official (thawte) cert and is ourside our firewall. This cert's common name does not match the server name (so it can be shared in our farm). So when we access the site, we do so using https://[commonname].com/web as opposed to https://[servername]/web. I tried the latter approach (I get cert errors that there is a name mismatch) but still have the same result.
Also, I can access the STS site directly and login fine there.

ASP.NET authentication is based on cookie by default. Cookie lives inside web domain.
So if you have two servers installed like this:
http://www.web.com
http://www.sts.com
WEB server cannot read cookie set by STS
There are two possible solutions:
Implement both servers as sub-domains
Store authentication ticket in URL instead of cookie
For option 1
Move servers as follows:
http://www.web.yourdomain.com
http://www.sts.yourdomain.com
Update web.config to scope cookie to yourdomain.com:
<authentication mode="Forms">
<forms domain=".yourdomain.com"/>
</authentication>
For storing ticket in url check this article - http://www.codeproject.com/Articles/2796/Cookieless-ASP-NET-forms-authentication
Update: Seems that I did not get that STS stands for Security Token Service. My answer is not relevant. :(

While redirecting from your STS server you will have to redirect using the AutoPostform which will submit the token to the Relying party.
And when Relying party will receive the token it will create the cookie against that user.
So next time whnen you will check User.Identity.IsAuthenticated at Relying party it will return you True.
Go throung the following link to know more,
http://chris.59north.com/post/2013/03/27/Claims-based-identities-in-ASPNET-MVC-45-using-the-standard-ASPNET-providers.aspx

We had the same issue when moving the RP to a different server. It turns out that we needed to go into the application pool -> advanced settings -> Set 'Load User Profile' = true.
After that, everything worked as it should on the new server and User.Identity.IsAuthenticated was returning 'true' after it came back from the STS.

Related

Why "requireSSL='true'" was throwing IIS error

I am working on MVC framework in ASP.NET where, I was trying to access the application but I was not able to go past the login screen, after which it kept throwing the not found IIS error. After workaround i found that i had this line : httpCookies httpOnlyCookies="true" requireSSL="true" in my web.config file which was stopping the access. Can anyone help me understand the problem and concept here?
Thanks already.
I was able to access the site after removing the requireSSL part only.
Web-config
httpCookies httpOnlyCookies="true" requireSSL="true"
Global.asax's Application Start :
if (ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Tls12) == false)
{
ServicePointManager.SecurityProtocol =
ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls12;
}
I think the part of code in global.asax's Application Start might be causing the problem, but I'm not sure about it.
Websites use cookies to store information between page requests or browsing sessions.
The callback from an external provider to your site contains security tokens(httpCookies) that allow access to your site and contain user information.
If someone manage to steal other's authentication cookie for a website, he could carry out all the actions that they are capable of.
Transmitting this information over HTTPS to prevent interception while this information travels over the Internet is important
You can stop script access to all cookies in your site by adding a simple flag: HttpOnly. You can set
this flag in the web.config, as follows:
<httpCookies domain="" httpOnlyCookies="true" requireSSL="false" />
So If you write requireSSL="true" in your Web.config It Enforcing the external provider to make their callbacks to your site using HTTPS only.
#Vishesh Pandita In your case you are trying to access site using HTTP only. So faced "HTTP Error 403 - 403.4 Forbidden: SSL required" error.It means the page you are trying to access is secured with Secure Sockets Layer (SSL).
Solution:
To view the page, you must enable SSL (Secure Sockets Layer) by typing "https://" instead of "http://" at the beginning of the address you are attempting to reach. The "s" in "https" specifies a secure site.
Migration for HTTP to HTTPs
source : Professional ASP.NET MVC 5

Authenticate all Subdomains in Multitenant Application

I have built a Multitenant SAAS application. In this application the User can pick his preferred subdomain name during signup. When user logins to the main application i.e. app.example.com, I validate his credentials and then redirect him to his preferred domain i.e. client1.example.com
I am using Forms Authentication and trying to authenticate the user over the domain "example.com" by making following changes in the web.config.
<forms loginUrl="~/Login/Home/AuthenticateLogin" timeout="2880" protection="All" domain=".domain.com"/>
My understanding is that once authenticated over "example.com" user will be able to access any subdomain of (domain.com). But it seems this does not happen as expected. After successful login to app.example.com when I redirect him to client1.example.com it again shows the login page.
What am I missing here?
You need to configure the same machineKeyfor all applications that share the authentication cookie. See Generate a Machine Key for a Web Farm (IIS 7).
Also verify that the cookie is set when you log in, and that it flows to all the applications.
Okay, So after trying for so long I got to know what the real problem was.
Actually even after allowing subdomains to share authentication cookie it did not work because the SessionId was not being shared between the subdomains. My Application had outproc Session Configuration (Sql Server). To share SessionId between subdomains I had to make following entry in my web.config :
<httpCookies domain=".domain.com"/>
After this it worked like a charm.
Hope this helps someone in need.

Using ASP.Net Identity on multiple web applications

I've got several applications hosted on the same IIS (different context roots), that are all protected using the Microsoft.ASPNet.Identity 2.1 NuGet packages. At the moment however, when I log in to one of the applications, the next visit to any of the other applications prompts me to log in again. I can't be logged in to more than just one of the applications at once.
I'm guessing that they are all using the same cookie to store the login token, so when you log in on one app, it resets the cookie which becomes invalid for requests to the other applications.
What are my options for resolving this? I don't mind having to log in to each app individually, so can each app be configured to use a different cookie?
Alternatively, each app does in fact share the same User table in the DB, so it might be possible to configure it so that when you log in to one of the applications, the others also become logged in.
Have a different cookie name for each app:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieName = "CookieNameHere",
});
As shown on this page http://tech.trailmax.info/2014/07/rename-authentication-cookie-name-of-asp-net-identity/
Yes, this is because on 'localhost' you are sharing the same cookie.
This will not happen on production, because cookies are domain only. (unless, of course, all applications are deployed to same domain).
This is kinda annoying on localhost but easy to solve. Just change the name of the cookie for each application.
This varies from identity version to version but something like this is what you are looking for :
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieName = "MyApp1", // <-- add this, with different names for each app
// ...
});
normally found on Startup.Auth.cs or Startup.cs file.
As of using the same cookie on all applications (if they share subdomain.domain) you need to get MachineKey (validationKey, and decryptionKey) AND same cookie name on all your applications.
something like this on web.config:
<machineKey
validationKey="..." <-- some valid validation key
decryptionKey="..." <-- some valid decryption key
validation="SHA1"
decryption="AES"/>
I think Single Sign-On could be your solution. Search for it on Google.
For your start up, you can refer couple of links below:
Single Sign-On Asp.Net
Claim base Single Sign-on for Web and Azure
Single Sign-on for existing MVC App
Hope this is what you are looking for and will resolve your problem.

Redirect after Session timeout (Grails, Spring Security Core, Tomcat)

I have an application developed in Grails (v1.3.7) and we used Spring Security Core (v1.2.6) plugin for authentication. After building .war file, I have deployed the application in a standard tomcat server (v7.0.22). The application runs fine.
I know that I can configure Session timeout period in web.xml either before building the application or in the tomcat server itself. But, I want (additionally) to redirect any page to the log-in page automatically whenever the Session is timed out. Because, if the Session times out and users click on any links or simply refresh the current page, they get a tomcat error.
Can anyone suggest a way to resolve it easily? Is there any configuration (like expired-session-url) in Tomcat or Spring Security Core that does the job?
I have search in the plugin doc site, plugin blog site but nothing found. This site suggest that I would require to add a listener in code and I would hate to do that and would like to use a simple configuration like this. Can anyone guide anything?
Thanks in anticipation
Http is stateless protocol, and session is just a marker stored on client cookies (+ local db), and you can't handle this as an event. 'new client' and 'session expired' is the exactly same, it just means that you can't identify browser for current request. For most cases it means also that user is not authenticated (for raw Spring Security Core, at least)
For you case, you already have session expired handler, it's when you're getting this tomcat error. Just handle this error, and redirect user to login page.
Btw, if you have proper Spring Security configuration, it must redirect all non-authorized users to login page. And seems that you have made something wrong with your app architecture, if you have authenticated user, but still having some user datails in standard tomcat session. There at least two ways: avoid your own user session, or make some kind of session-based Spring Security authentication config.

Forms authentication & subdomain

I'm trying to use forms authentication that will work for both my top level domain & sub domains.
for example, if I log in with this domain: mydomain.com and afterwards going to www.mydomain.com i want to have the ability to identify the user who logged on to mydomain.com (it's the same application).
i'm using the following in my web.config file:
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" domain="mydomain.com" timeout="2880" />
</authentication>
This is an mvc project, and i'm getting the user id with the following API:
HttpContext.Current.User.Identity.Name
The creation of form authentication cookie is done by the following api after performing openid logon to the user:
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
I can see that the authentication cookie is being sent to both domain but only the domain that the authentication was made against recognizes the user.
Am i doing something wrong?
Thanks,
Lior
Make sure you have the same machine keys setup for those two applications. If the authentication token is encrypted with the machine key of application 1 and application 2 has different key it won't be able to decrypt it.
This question isn't exactly the same as yours, but it looks like it's the solution your looking for.
You need to issue your ticket in the toplevel domain, in order to be recognized by subdomains. This is because of how cookies work:
If you set the cookie in domain.com it will be visible on sub.domain.com
However if you set it on sub.domain.com, it will not be visible on domain.com
This is a security issue because of cookies and you'll have to consider it, beyond the settings of the <form> element which have to do with validating/rejecting a authentication cookie, where you will need to have domain='domain.com', which you already do.
In addition to all this, if on the subdomain you have a different application, you will need to explicitly define the machine key to be the same. You can generate your self some keys here: http://aspnetresources.com/tools/machineKey

Resources