WS FEDERATION AUTHENTICATION MODULE Signout in ASPNET not clearing/expiring session cookies - asp.net-mvc

According to documentations- https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.services.wsfederationauthenticationmodule.signout?view=netframework-4.8#System_IdentityModel_Services_WSFederationAuthenticationModule_SignOut_System_Boolean_ and https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.services.sessionauthenticationmodule.signout?view=netframework-4.8 should clear all the sessions in application. But after calling WSFederationAuthenticationModule .SignOut(true) and SessionAuthenticationModule.SignOut() those session still remains valid. I am using .NET Framework 4.5.
To make cookie configuration SameSite=none the cookies must be made secure which we have done in Web.config file. But the WS Fed Authentication Sign out is not clearing the sessions as per the documentations. Reference- https://support.okta.com/help/s/article/FAQ-How-Chrome-80-Update-for-SameSite-by-default-Potentially-Impacts-Your-Okta-Environment.
I think this is due to buggy WS FED module by .NET Framework. Any help is much appreciated. Thanks.

Just to help others out with this same problem.
You have to change the "No SameSite" rule to also check for the "secure" flag. Like this:
<add input="{RESPONSE_Set_Cookie}" pattern="; secure" />
This is because WSFederation will do the clearing of the cookies without adding the secure flag and without the secure flag, chrome ignores the set cookie request to clear the cookies.
You don't need to do anything else, like clear/set the cookies manually, just use the SignOut() method provided by the WSFederationAuthenticationModule.

Related

Spring Saml2 and Spring Session - SavedRequest not retrieved (cannot redirect to requested page after authentication / InResponseTo exception)

I am trying to use Spring Boot SAML2 + Spring Session to secure my web application (to be deployed on K8S). Everything is fine without spring-session-data-rest or spring-session-hazelcast. It can authenticate with Okta and redirect back to the requested page after authentication. Also, I can use either opensaml3 or opensaml4.
However, when I tried to use either spring-session-data-rest or spring-session-hazelcast (just 1 instance, no cluster yet), it would not redirect back to the requested page. Also, it'd fail with opensaml4 with exception: "The response contained an InResponseTo attribute [] but no saved authentication request was found". There's some mentioning about opensaml3 going EOL so I want to make it work with opensaml4.
Here's a sample application to demonstrate my case https://github.com/simonckw/redis-saml2/tree/redis. Have I missed anything? Have anyone got a working sample with this setup? Help is much appreciated.
p.s. I've traced into HttpSessionRequestCache.java, invoked from SavedRequestAwareWarpper.java. Without spring-session-data-rest or spring-session-hazelcast, the saved request can be retrieved but not when either spring-session-data-rest or spring-session-hazelcast is enabled. It also seems to me that the InResponseTo exception could be related too. My Redis setup should be fine. Here's the session data written into Redis:
"spring:session:sessions:expires:7c1858d1-0ea7-4a7a-8523-2abf89137771"
"spring:session:expirations:1654439580000"
"spring:session:sessions:expires:58a584d3-625e-4e0a-bef5-3aaff485ad93"
"spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:abc#xyz.com"
"spring:session:sessions:7c1858d1-0ea7-4a7a-8523-2abf89137771"
"spring:session:sessions:58a584d3-625e-4e0a-bef5-3aaff485ad93"
127.0.0.1:6379> hkeys spring:session:sessions:7c1858d1-0ea7-4a7a-8523-2abf89137771
"sessionAttr:SPRING_SECURITY_SAVED_REQUEST"
"lastAccessedTime"
"maxInactiveInterval"
"creationTime"
"sessionAttr:org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository.SAML2_AUTHN_REQUEST"
127.0.0.1:6379> hkeys spring:session:sessions:58a584d3-625e-4e0a-bef5-3aaff485ad93
"maxInactiveInterval"
"creationTime"
"lastAccessedTime"
"sessionAttr:SPRING_SECURITY_CONTEXT"
"sessionAttr:SPRING_SECURITY_LAST_EXCEPTION"
The problem is that Spring Session is setting SameSite=Lax for its SESSION cookie. Your servlet container isn't setting that on JSESSIONID (when you're not using Spring Session).
Because the SAML response is being POSTed from Okta's page, the browser will not send the cookie, so Spring doesn't think it has a session in which to find the authentication request. It uses that saved request to reconcile the InResponseTo attribute.
You can work around this by removing SameSite from the cookie. Create a bean like this:
#Bean
public DefaultCookieSerializerCustomizer cookieSerializerCustomizer() {
return cookieSerializer -> {
cookieSerializer.setSameSite(null);
};
}
Alternatively, you could explicitly specify None, but then you would have to also set the Secure attribute.
Note: Chrome is supposed to default to Lax where SameSite isn't specified. In reality, it doesn't do that if HttpOnly is set. Safari and Firefox don't even seem to care about HttpOnly.
This problem is discussed here.

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

rails session steal through cookies

My question is different it's rather conceptual - As when a user login, session is created on server and it stores a unique id to client(browser) what if I copy that cryptographically signed cookie and any associate data from browser like token whatever app uses to recognize the machine, paste it or create it on another machine?
How would server recognize that? could someone Explain me as much you can? that would be a help
I tried finding the solution.
or how can I secure that? :)
As far as I know, only the user-identifying token in the Rails session cookie identifies the user. By sending that token (which happens automatically on each request), the server knows who you are. Anyone having that token will be treated by the server as if it were you. This is called Session hijacking.
There are a few things you can do to protect your user's cookies. First of all, secure your cookies by setting two flags:
secure tells the browser to send that cookie only over HTTPS, so it is protected against someone reading your traffic (and your cookie).
HttpOnly tells the browser to hide that cookie from Javascript, which improves protection against XSS (Cross Site Scripting). An attacker may find a way to inject some malicious Javascript, but the browser won't give it your session cookie.
On setting these flags, see the Rails API. For custom cookies it's basically:
cookies[:my_cookie] = { value: '...', secure: true, httponly: true}
For configuring the Rails session cookie, see this answer.
Recently, I have written a middleware that sets both flags automatically to any cookie in the application. It is called safe_cookies and we're using it in order to protect our applications.

In MVC what does the httpOnlyCookies attribute actually do?

I'm confused as to what this setting actually does.
According to MSDN, "Gets or sets a value indicating whether the support for the browser's HttpOnly cookie is enabled."
But I'm struggling to understand what this actually means.
The problem I am having is that in my MVC application, the session cookie is not being sent with the secure flag. I've put the RequireSSL="True" attribute in both forms and cookies sections of the web config, but the session ID cookie is still not sent under SSL. I was wondering if this other attribute was connected with it.
If you've implemented requireSSL="true", your cookies should only be transmitted over the HTTPS protocol. Nothing more should be required for that. The HttpOnly flag tells the browser that the cookie should only be accessed by the server -- not by any client-side script. This prevents certain XSS attacks in modern browsers that respect this flag (should be pretty much all at this point).

RememberMe with DotNetOpenId in ASP.NET MVC

Using DotNetOpenAuth 3 in ASP.NET MVC and implementing a RememberMe facility ...
I'm finding that even if I set createPersistentCookie to true in FormsAuthentication.RedirectFromLoginPage and FormsAuthentication.SetAuthCookie the user is not remembered once the ASP.NET session times out.
If I inspect the cookie I find it is marked as persistent and does have an expiry date way in the future, I assume because I set my web.config FORMS timeout to a few years away. Anyhow, if the user closes the browser and re-opens it they are remembered correctly - as long as the ASP session hasn't timed out.
An older post of Scott Hanselmann's makes me wonder if it is because FormsAuthentication tries to renew the authentication ticket and maybe in an OpenId model that doesn't work but I have set FORMS SlidingExpiration="false" in web.config and anyway I thought that forcing a persistent cookie would make that stuff irrelevant.
I'm also wondering why the DotNetOpenId MVC sample doesn't include a RememberMe checkbox - maybe there's something tricky about it?
On the other hand, here at StackOverflow I see I am automatically remembered across sessions. Wondering whether they used something other than DotNetOpenId to do their OpenId authentication.
Anybody else done RememberMe successfully with DotNetOpenId in ASP.NET MVC? Any tricks?
[Update]
Thanks for trying to help, Andrew. Turns out this was not about DotNetOpenId.
I gather, after reading this, that my hosting provider is probably recycling the app pool regularly and that's causing the authentication ticket encryption to be done with a new machine key.
As per the preceding linked article I added the following under System.Web in my Web.Config and it resolved the issue:
<machineKey
validationKey="(generated a new key to place here)"
decryptionKey="(generated a new key to place here)"
validation="SHA1"
decryption="AES" />
I still think the cookie name should match... but here's something else.
It sounds like you're saying as long as your timeout in the web.config file is large, then things work. But that once you shorten it, your persistent cookie doesn't outlast the timeout value. This forum topic helped answer this for me:
http://forums.asp.net/p/1010241/1347970.aspx#1347970
It seems that the timeout in web.config affects all cookies. It says how long the authentication ticket lasts. All auth cookies have this 'time to live' timeout whether they are 'persistent' or not. So the difference between persistent cookies and non-persistent cookies are that the former will last across different browser sessions and the latter will die (early) if the browser is closed.
Does that make sense?
Does the cookie name match in your web.config file and your controller's call to FormsAuthentication.SetAuthCookie? This may be a bug in the DNOI sample, but I suspect if you have a cookie name in your web.config file (as the DNOI sample does), then you probably have to set the cookie name as the third parameter to SetAuthCookie or RedirectFromLoginPage. Otherwise, forms auth doesn't recognize the persistent cookie you set as the login cookie.

Resources