I am using Azure Active Directory Single Sign On. I want help in following basic questions:
What is the default session timeout once the user login to the site?
Currently we are observing the timeout is very short, how can we increase it?
It really depends on how you secured your site. The most common strategy entails mirroring the validity window of the token used to initiate the session. Assuming you used OpenId Connect, that would be 1 hour.
You can change the default behavior by decoupling the duration of your own session from the validity window of the token. If you are using OWIN middleware, you can pass in the protocol options UseTokenLifetime = false. The same approach will work with both WS-Federation and OpenID Connect middlewares.
Related
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.
I am in the midst of designing a single auth model that works for both SPA+API server and web applications.
Got some insight from the here link to use access/id token in cookie form (none httpOnly) for web application integration.
Attempting the OIDC public client and PKCE way, the integration is workable for SPA+API server but I am stuck at the token
renewal flow for the traditional web application. Oidc silence renewal flow is pretty front channel initiated and when the access token is expired, what will be the options for web application to retrieve the new access token ? (assuming the session from IdP is not expired)
You should use the OpenID Connect hybrid flow. This will issue tokens to your front-end and traditional back-end Web app. It will also allow you to issue different kinds of tokens with different claims to each.
More specifically, the front-end may only get:
An ID token; or
An ID token and access token; or
An ID token and access token and a refresh token.
Also, the back-end may only be issued any combination of these.
You can test the hybrid flow if you're unfamiliar with it using oauth.tools.
For the front-end, you have a couple option to continue access the protected resources without prompting the user:
Rely on SSO (the front-channel approach you mention) or
Issue the SPA a refresh token
In the refresh case, take note of the best common practice for this:
The refresh token should be created anew whenever it's redeemed
Refresh tokens must expire by a certain time or after a certain period of inactivity
Renewed refresh tokens must not be renewed beyond the lifetime of the original
If you do these things, there's still risk involved in issuing an SPA a refresh token, so consider:
Not issuing one or
Doing a combo of the two approaches
When doing a combination (SSO + RT), you could cap the lifetime of the refresh token to something that shouldn't greatly impact the user's interaction with the API while still requiring them to prove control of the original credential with some amount of frequency that offsets the risk. In such a case, the friction of having to login could be lessed by allowing SSO at the authorization server. This too introduces risk, so its lifetime should be limited.
I would look at all these timeouts as knobs that you can turn and twist to ensure an adequate amount of security.
Extending the period of access for the traditional, back-end application can be done using the same two options (SSO or RT).
I am trying to enforce user logout after a period of inactivity, but I have had no luck.
I have a node web application that is using Auth0 and Passport for authentication. I have set the inactivity timeout on the tenant (from the tenant settings page on Auth0) and modified the jwt expiration on the application settings page, but none of these changes have had an effect on the behavior of the application.
Other information: in the application settings, I have set this as a Regular Web Application, and I have tried Basic and Post for Token Endpoint Authentication Method.
I have followed the node JS quickstart guide that Auth0 provides, as well as one of their blog posts using express-session, passport, and passport-auth0. I am configuring express-session and passport in the order that these two posts show, so I don't think that is the issue. I am guessing that there is an extra step needed to implement this functionality, but I can't find any documentation on Auth0's site or Passport's. I am also confused as to why these values are configurable if they don't seem to have any effect.
When I manually set the maxAge value in express-session's settings, I do see the application make a call to Auth0. However, this is not based on inactivity, and that is my primary goal here.
I work with the Auth0 Community and you are able to configure this as a setting with your Auth0 Tenant as described in the below documentation:
The intent of this approach allows the session to go inactive if the
user is no longer present, but otherwise provides a means to trigger
the silent token refresh so that they can continue their session
without the need to be prompted again for credentials.
Inactivity Timer: A rolling timer should be added to the React SDK
wrapper that aligns with the maximum idle lifetime of the Auth0
session. Each time a token is returned to the application the timer
should be reset.
Timeout Modal: When the timer hits 60 seconds from expiration a
timeout modal should render requesting the user to logout or continue
their session.
Continue the session: In the case the user chooses to continue their
session the getTokenSilently() method can be used to request a new
token without needing to redirect the user from the page they are
currently interacting with.
Logging out: In the case the user chooses to logout the logout()
method should be called to assure the Auth0 session is ended as well.
Idle Timeout: In the case that the idle timeout is reached no
immediate action is necessary. To handle the fact that the user may
still be active in another tab, the behavior should not be to log the
user out.
https://auth0.com/docs/sessions/concepts/session-lifetime
I hope this helps you on your quest!
I'm using passport-saml/multiSamlStrategy (using IdP initiated flow only if that matters somehow).
I want to verify periodically that the user is still logged in to the IdP and logging him out in case he isn't.
The problem is that req.isAuthenticated() always returns true since it consider only the session of the web app and not the IdP session.
In case the user is connecting directly to the IdP and log out himself from the IdP, I would expect the req.isAuthenticated() to return false.
How can I achieve that? Is that Possible?
SAML protocol perspective: there's no way to determine if the session is alive at IdP.
The closest approximation involves a Single Logout (SLO) profile in SAML. IF both identity provider and service provider (your app) support SLO, the IdP could have a Logout button that works like this:
After clicking Logout in IdP, the IdP sends a LogoutRequest message to all service providers asking them to terminate their sessions.
At roughly the same time, IdP terminates its own session.
SLO might work under a number of carefully curated assumptions. In practice there are a number of issues with "single logout". Top two problems - asynchronous nature of the protocol and "ownership" of (what is essentially) a shared authentication context in a multi-SP scenario. This Stanford article does a good job of outlining some of these concerns. This is why SLO is rarely used and the recommended option for service providers is to manage their own session only without thinking about the IdP.
I know that web apps don't normally tie their sessions to the sessions of their login providers, but I have a requirement in which I need to detect when the user signs out of their login provider so that I can sign them out from our application as well.
I currently have passport set up on my Node.js server. The login was very easy to implement and it's been working fine, but I haven't been able to find documentation on polling the current status of the user's session on the provider's end. Does passport provide a means to check this status? Calling the authenticate route again always does a redirect so I'm looking for a simple and ajax-friendly way to get a yes or no answer to the question: 'Does the user still have a valid session at their login provider's end? Thanks
This is going to depend on the provider and the protocols they choose to implement. What provider are you using? What protocol is used to authenticate?
Currently, SAML is the only widely-used standard which defines facilities for federated session management. Even in that case, I'm not sure how common those profiles are, since it is typically used for authentication only.
As far as Passport is concerned, that module is focused solely on authentication. Session management and logout are separate (but related) concerns. I'd like to develop other modules that work in conjunction with Passport; however, lack of deployed standards make it difficult.