Federated authentication and session management - security

When you login to Identityserver the authentication cookie idsrv is stored in the browser. When the user logs out, the cookie is deleted. However, an attacker can steal the cookie and essentially use it even though the user has logged out.
This seems to be "normal" behavior for many identity providers too.
Question
Is it accepted behavior?
Is there anyway to detect that the user has logged out and that the idsrv cookie value (token) is no longer valid? Should we for example implement IAuthenticationSessionValidator to keep track of the users that are signed out? Or is this something that should belong to the application by using the id_token session_state claim?

According to OWASP ASVS requirement 3.2 Sessions should be invalidated on user logout it should not be possible to use the same cookie after logging out of the application. This also is the case if using other identity providers like ADFS and AAD.

Related

IdP as the master session

Background
I'm trying implement a browser-based login for a native mobile app from an existing Single Page Application. It uses WebView to render the SPA and it uses Keycloak OIDC as its Identity Provider.
The SPA and IdP is located in completely different domain and authentication is done by redirecting to the SPA domain after a successful login and retrieving the active session (cookie) from IdP domain in one of the SPA's server. The authentication check is achieved by using keycloak middleware which I believe is the protect.js
Summary:
Perform Login -> auth.idp.com
Redirect -> best.app.com
Is Login? -> best.app.com/login
Does auth.idp.com session exists?
User is logged in, redirect -> best.app.com
Token is passed in the URL and is stored only in memory
Token is used to establish WebSocket connection
Issue
Based from the spec, the authorization should happen in the browser / in-app browser, and authorization code must be passed via custom URL scheme. Having that in mind, the SPA that resides in the WebView of native mobile app will never establish a session from IdP's domain since this will be delegated from the browser which is on a different process and obviously using a different cookie store than on WebView in the mobile app, which makes our existing solution to break because it is relying on the IdP's domain cookie.
Proposed Solution
The issue I described above can be mitigated by cutting the reliance on IdP's session and by managing the SPA's own session, which basically means storing the token persistently that can be obtained from the IdP (which the current solution doesn't do).
(I don't want to detail much of the solution since I just want to focus first on the concept of storing the token. I think it's better for me to put this in a separate discussion if someone is interested)
Opinion
It seems like the current implementation doesn't really follow the best practice for OIDC flow but somehow, Keycloak has made some middleware to remove the need to use these tokens (authorization code, id token, and access token)
Relying on IdP's session when implementing SPA or non-web apps seems like not an option, because there is no way to obtain the cookie without reloading the page and provided that IdP session exists in the same cookie store as the SPA.
Redirecting to the IdP's session is not a good user experience for SPA. See the same sentiment here but it seems it does not have any answer: https://lists.jboss.org/pipermail/keycloak-user/2016-October/007937.html
Question
With regards to my proposed solution, i.e., storing the token retrieved from IdP, is there any security flaw or something non-industry standard it's going to introduce? If so, what are those?
Is it typical for OIDC flow to rely on IdP's session (cookie) to check if user is logged in or not?
If answer from #2 is NO, is that authentication flow specific for Keycloak only or does it exists for other IdP as well?
If answer from #2 is YES, is it common for IAM solution to programmatically check if the IdP domain contains a valid session (cookie)?
Is the current implementation flawed knowing we are aiming for SPA?
How does Keycloak handle sessions?
If you're using the default Keycloak middleware in your server and use keycloak.protect() for protecting endpoints, it checks on the request.session['keycloak-token'] which contains the access_token that was created during the token request after user login. If this exist and valid, it means user will not be redirected to Keycloak login page.
How does Keycloak create sessions?
Providing username and password which can be done manually using Keycloak's login page.
Cookies - if you pass valid cookies that are recognized by Keycloak, i.e., KEYCLOAK_SESSION, KEYCLOAK_SESSION_LEGACY, ..., a session will automatically be created.
How to access protected resources?
When using the keycloak-connect client adapters, you can access protected resources if the user agent (browser/app), has a valid session in your server OR if the request contains valid Authorization header.
Standard Solution
Access protected resource via Authorization header and use access_token which the keycloak.protect() also accepts. You can obtain this token in a standard way using Chrome Custom Tabs for Android and ASWebAuthenticationSession for iOS. You can also use AppAuth (iOS, Android) to lessen your work.
Store the refresh_token and access_token from native mobile and inject this in the HTTP request of WebView if possible.
Have a way to check for access_token validity and use refresh_token to request for a new one. If requesting for a new one fails, i.e., the authorization server verifies it's not valid anymore, that means users would need to re login again.
By using the standard solution I have proposed above, you should not need to create a band-aid solution for your issue. Hope this helps anyone that have faced similar issue.

in ASP.NET Web API, How to de-authorize a user immediately after account lock-out or delete?

I'm building a new Web API application using OWIN cookie authentication (ASP.NET Identity 2.2) for security.
I'm new to the whole cookies thing, but I've got a head-scratching problem: How is a logged-in user immediately blocked from using the API if their account has been deactivated (either deleted or locked-out)?
This arises after a startling discovery that if I have a user logged in on a client app, and I delete their user account via a different app, they are still able to access the API (i.e. the [Authorize] filter still succeeds because their cookie is still valid).
Somebody please correct me if I'm wrong, but AFAIK, cookies are not stored on the server, so there is no way to "invalidate" the cookie.
Yes, if the user logs out, they won't be able to log back in again. Also, I understand that setting an expiry on every cookie upon successful login will mitigate the problem.
But what about the following scenario: a system administrator (let's call him JoeAdmin) gets fired or otherwise becomes untrusted and some other administrator locks out his account. If JoeAdmin happened to be logged in when he got fired and became disgruntled, he still has access to the system and can do some real damage.
In this scenario, how could JoeAdmin be blocked immediately?
JoeAdmin happened to be logged in when he got fired and became disgruntled
Also JoeAdmin could have saved the cookie value offline, awaiting for his account to be revoked, and then later restores the cookie value to his browser.
OWIN cookie authentication is not ideal if you ever need to immediately invalidate logins.
This is because all the state information about the user is stored client-side, authenticated with a secret only on the server-side.
That said, you could do something with Oauth2 refresh tokens like here. e.g. have an access token that expires after say a minute, which when expired the application has to use a refresh token in order to gain an access token for another minute.
This way, any revoked accounts are only exposed for a short time. However, you may need to deal with the complexity of out-of-sync clocks on client and server.
Long story short, if you need to secure your system in this way, traditional server-side tokens would be the way to go. They are more secure in this regard.
The risks with using OWIN cookies are very similar to those of using JWT's for authentication. See this comment and the associated question and answer.

The way of STS token storing after validation

I need additional clarification.
If I got correctly from this link Where Federation authentication token is saved [WIF STS]? and other general WIF-STS discussions, STS token is in default scenario stored in cookie in an browser. In my browser it is split in two cookies started with FedAuth. It is OK. If I understood good, cookie is created by WIF after STS token validation on RolePlayer application. If it is like that, then cookie is in RolePlayer application domain. When user hit RolePlayer2 application (that is in federation and in second domain) then how STS knows about that user, when it has not access to created cookie.
Could you clarify this to me please ?
Refer: AD FS 2.0: How to Use Fiddler Web Debugger to Analyze a WS-Federation Passive Sign-In
You'll see the MSIS* cookies are used for ADFS as opposed to the FedAuth cookies that are used for the application.
So you navigate to RolePlayer2, redirects to ADFS, sees you already have a cookie i.e. have authenticated and mints the FedAuth cookies for that domain/application without asking you to login.

Can a SP request on behalf of the user using SAML

A bit of background may help. I'm looking to authenticate a user using SAML, but I want to maintain the look-and-feel of the login experience to the best of my ability. I've looked into OpenSAML a bit, but not extensively since I'm not sure this can be done yet. So, if I have a login service that can retrieve the username/password from the user, can I programmatically issue a SAML request to an IdP to authenticate said user without having to go through the entire XHTML form processing steps?
Your question is more about how to Authenticate the user and less about SAML. SAML doesn't really dictate how a user gets authenticated at the IDP and it definitely doesn't handle your use case. As a 3rd Party SAM SP, it is not recommended you ever prompt a user for their credentials for security reasons since Enterprises only want users entering credentials into "Corporate branded" login pages to reduce phishing and other password based vulnerabilities. Besides, how can your customer trust that you are not storing users passwords if they are entering them on your site? Let the IDP handle the user login, it is just one of the many benefits of using SAML. HTH- Ian

How to forcibly ask authentication for a web resource for every access?

I have some webserver resources protected with Form based Authentication. The requirement is to have some highly secure resources access result in forced authentication of the user even if he/she is authenticated earlier and have a valid cookie (authentication).
The authentication in a session is maintained by a particular cookie. The first idea to solve this problem is to pass that cookie with "expires" value with back date. But for the form login it is not working, I am getting only login page everytime after providing correct credentials. Cookie with expire value with back date is encountered, cookie is deleted by browser. So this cycle of login is encountered.
Please advise me on what to do.
At this point authentication isn't enough. You're going to have to implement multiple levels of authorization, with some levels not having persistent tokens. There's a number of resources on the Internet that explain token-based auth.
Basic authentication (not to be confused with the HTTP scheme of the same name) uses only a single token to determine whether the user is logged in or not. Just split the application into multiple authz token realms and handle it from there.

Resources