Background
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?
CodePudding user response:
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 useaccess_token
which the keycloak.protect() also accepts. You can obtain this token in a standard way usingChrome Custom Tabs
for Android andASWebAuthenticationSession
for iOS. You can also useAppAuth
(iOS, Android) to lessen your work. - Store the
refresh_token
andaccess_token
from native mobile and inject this in the HTTP request ofWebView
if possible. - Have a way to check for
access_token
validity and userefresh_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.