I am exploring keycloak for my project SSO solution, and I am trying the open-connect on this blog https://developers.redhat.com/blog/2017/05/25/easily-secure-your-spring-boot-applications-with-keycloak/
And I would like to as one question about Single Sign Out, I would like to know what’s the principle behind. Tried to search online document but I didn’t find any clue .For a while, I was thinking there is no elegant solution for Single Sign Out in oauth2 world.
This is the way Keycloak implements it (yes, this is not part of OAuth):
when you use Keycloak to create a server side session in your application using the Java Client, Keycloak will trigger a logout of the session once the logout at Keycloak is triggered. You'll need to set up an Admin URL for your application in Keycloak. This is called "backchannel logout" in the documentation.
When you use Keycloak in a HTML5 client, Keycloak will create a hidden IFRAME that will check that the Keycloak-Cookie is still present. If it is not, the HTML5 application knows that you have been logged out.
OpenID Connect Back-Channel Logout seems to be the way to go nowadays. It works by exposing a special end-point in your application (backchannel_logout_uri), which will be invoked by the OpenID Provider when the user logs out from SSO. Through this endpoint, the Provider gives you a signed Logout Token, to notify your application that the user's session should be terminated.
Because a user may be logged in from multiple devices, browsers, etc., the OpenID Provider can also include a Session ID (sid claim) as part of the Logout token. You can compare it with the sid that you would have received in the ID Token during login, to decide which session to terminate.
The standard back-channel logout was implemented in Keycloak 12.0, which shipped in December 2020. Earlier versions only implemented an alternative, proprietary mechanism.
Related
I am confused about the different login methods and the impacts on the user experience.
I would like to do native mobile app login on iOS, that means the user is not redirected toward the web page (or in app browser tab) to login. For example : All banking applications (Ex: N26) the login method is always the same : User enter his login / pwd and then he connects.
However, when I see the "Best practice login app for mobile" I can see they use authenticate + authorization code flow with PKCE. But using this method, my mobile app has to be redirected to the authorization server (Like when we want to connect with google).
So my questions are :
Is is possible to do native login using authorization code flow with PKCE without opening an in app browser tab ?
In terms of security, authorization code flow is better than native ? If yes, why all banking mobile applications are not using it ?
if the authorization server is the same than the resources server, is it possible to not have this redirection for the login ?
For now, my server use OpenID, tomorrow maybe OpenIDConnect.
Thank you for your answer :D.
Context
N26 as well as most banking apps do not support Single-Sign-On (SSO).
Auth code flow + PKCE is a way of securely having your user login with SSO, usually using a well known Identity Provider (IdP) as Google. Then, assuming your selected IdP follows the OIDC specs, you will be able to receive an idToken which will represent the user who just logged in and some of her details (called token claims) like her email, name, etc.
Answers
Auth code flow + PKCE is related only when you use OIDC SSO, not with native login.
In order to implement a native login you would have to be the "authority" who keeps the data required to authenticate users like email, password etc. Otherwise, Google (or any other IdP) is responsible for that. SSO provides better UX (as long as the redirect to the IdP is not poorly designed) and users prefer it since they are usually already logged in to their IdP, thus they do not have to remember and type credentials. However, the reason that lots of banks do not use SSO is that they do not trust Google. If Google gets compromised, the malicious party would be able to issue tokens that would allow them to impersonate anyone. Same for availability. If Google goes offline for some reason, users will not be able to login. I guess banks believe that they can provide better security and availability guarantees on their own.
Again, you need the redirection only when using SSO OIDC. If you are not using that, and end up using a native login no redirection will be needed. That being said, it is a good practice too keep your authentication server separate to your back end.
I need to login to Auth0 without login prompt on my intranet under certain circumstances.
I have a very particular use-case, where I have created a very special user in auth0 called "analytics" which has access to some of our analytics in Tableau.
I created it, so I know the login password and can create refresh tokens with unlimited life.
I had to create this user in auth0 and have it managed by auth0 because that's how our company access Tableau and I can't change this policy.
In another web application, which doesn't use Auth0 at all and has its own authentication methods, I need some users to have access to the ressources that the "analytics" user can access. (there also, no way to change this web application to use Auth0, because that's another company policy and I can't change it)
To achieve this, I have no choice but to allow all logged in users of the web application to be also automatically logged in as "analytics" in auth0.
Since this is an intranet, it is perfectly ok to hardcode a refresh token or login password. Also there's nothing too confidential about the analytics in question.
I know how to use the refresh token to call an API, but I don't know how to use it to "login" the user, e.g. his browser has the right cookie so auth0 knows that his browser is indeed him.
Is there any way to achieve this ?
I don't understand very well the OAuth 2.0 protocol, hence my question.
Does ORY Hydra currently have a feature that verifies if a client is logged in via OpenID Connect? I notice there is an API to logout via front-channel
When a user revisits the identity provider, however, I have no way of knowing if they are currently logged in or not. They could delete their client-side HTTP cookies and then I am out of sync with Hydra. Meaning: Hydra has them as logged in, but I have them now as logged out. Also, in the event of a back-channel logout, I want to be able to query for this state.
Is there an API I am overlooking that allows me to know whether a client currently has an active OpenID Connect login via Hydra?
It appears as of right now the only thing one can do is redirect the user to the authorization endpoint since we have no way of knowing if they are authorized or not.
The following two tables that ship with Hydra seem to be the source of truth for the data I am after: hydra_oauth2_access and hydra_oauth2_authentication_session. Does it ever make sense to query those directly if there is no supported HTTP API out of the box to see if a user has an active authentication session?
Sending an authentication request via a redirect to the Provider including prompt=none addresses this use case: it will silently login and return new tokens if there's an ongoing SSO session at the Provider, it will return an error code login_required if not.
Notice there will never be explicit user interaction in both cases so this is convenient (and meant) to run in an hidden iframe.
LOGGED IN STATE
An OAuth client is most commonly a UI application with multiple users. Each user's logged in state is represented by an Authorization Server session cookie that neither the application or user have access to:
The Authorization Server (AS) issues an SSO cookie, to be stored in the system browser for the AS domain
Both Web UIs and Native UIs send it implicitly on subsequent requests, when they invoke the system browser
AUTHORIZATION REDIRECTS
When an OAuth UI redirects the user, it is generally unknown whether:
The user will be prompted to login
The user will be signed in silently (eg the user could have signed in to another app)
For a Web UI it is possible to send an authorization redirect on a hidden iframe with a prompt=none parameter. If the user needs to sign in a login_required error code will be returned. See my Silent Token Renewal Page for further details.
This is not fully reliable however, and has some browser issues in 2020. Also it may be unsuitable if you are using a different type of client.
FEDERATED LOGINS
In some setups the AS redirects further to an Identity Provider (IDP), and the user's login state is further influenced by an IDP session cookie.
There is no way for an app to get hold of the user's IDP login state, since the app only ever interacts with the AS.
IS THERE A USABILITY PROBLEM?
If so, post back and we can discuss further ...
At my company we are developing several web applications that uses a REST API server.
First a little introduction.
The app provides the ability to manage users through the REST API and allows the users to login to the app.
Right now the REST API is for internal use only because we plan to develop more apps and communicate to the REST API as the central point of data access. We are handling the REST API authentication with a "Resource Owner Password Credentials Grant" implementation for the internal apps.
What we need is a Single-Sign on service for all the apps, we want a user to login to an app and if he/she access to another of our apps he/she will be already loged in.
We have been experimenting with the CAS protocol, with the CASino library specifically and it works great.
The problem is we don't know how to handle the flow between the apps, the REST API and the SSO service, also I don't know if there is a better choice regarding SSO services.
My questions are...
How we could handle the flow between the apps, the REST API and the
SSO service, because the REST API should be stateless it should not
communicate to the SSO service? or is there a way to communicate the
REST API to the SSO service?
Is there a better choice to implement a Single-Sign on service,
maybe OAth or OpenID and are this options suitable for REST APIs?
Thanks in advance!
Your REST API will have to talk to the SSO server to validate the Access Token, unless all the information it needs is encrypted inside the Access Token. Not sure what you mean by "flow between the apps", you should have all apps talking to a central SSO server.
When a user wants to create an account on WebApp1, the account should be created on the SSO server, either by redirecting them there or if you need a differently styled signup form for each web app, then via an AJAX call to the SSO server's REST API. I would recommend the latter as redirecting is more difficult to debug and it can make a bad user experience.
Make sure the messaging is clear, i.e. not "Sign up for a WebApp1 account", but "Sign up for a MyCompany account to get access to WebApp1".
OAuth 2.0 is very popular and people have more experience with it, so it's easier to get help or integrate with apps created by others.
The doorkeeper gem is a good server library.
OAuth 2.0 is normally used when the SSO server doesn't trust the client apps (e.g. Facebook, Twitter), but it can be implemented in such a way to skip the client authorization step (where the user is asked to approve the client app), and you can use the Resource Owner Password Credentials Grant via a REST API.
CAS is easier than OAuth. It is fairly easy to implement the basic endpoints and that way you can customize it as you wish.
I worked on a CAS-based server with a custom implementation (not sure if it was even really CAS-compliant). The authentication was done with Devise (I don't recommend Devise if you're going to customise it a lot, make your own in this case). The original flow was that the user went to the website, clicked Login/Register and then was redirected to the SSO server and after the user logged in, redirected back with a one-time ticket that the website's backend exchanged to an access token via a REST API call.
Then we added a REST API that was called from each website with AJAX. You send the username/password/captcha/etc and get back an auth token, which the site sends to its own backend. The SSO REST API can also set a cookie on its own domain, so that if the user visit another of our web apps it makes a call on pageload to check if the user is logged in. This way you're automatically logged in on every webapp without the redirect mess.
All tokens issued + the associated user info were sent to a fast Node.js app that would save them to Redis, and the app backends would call this app to validate the access tokens really fast, without putting load to the SSO Rails app.
As background, I'm using the Google OAuth2 NodeJS client, but I think my question is more abstract / technology independent.
My website is single-page application that communicates via AJAX to the server.
When a user first visits my website, I perform an OAuth2 flow which redirects them to Google to log in, and then redirects back to my site with an access token. I store this access token in a cookie, and use it to handle various calls made to the server via AJAX.
My challenge is that I'm unsure what to do when that access_token expires. Should I be storing the refresh_token in a cookie as well, and using that, or are there security issues in doing so?
Should I be redirecting the browser to perform the login flow again? That seems fairly ugly for a single-page application.
You can do the OAuth2 flow via js in the background(like the login flow with the popup window), and if the access hasn't been revoked for you app id, then the user shouldn't see anything about it. Although you can set a hint on the user email to authenticate, this may not work.
The other way that you mentioned, is the refresh token, that you can use to ask for a new access token, without user interaction. Maybe that would be the better idea, but remember, that you will only get a refresh token if you set the access type to offline.