Transfer Keycloak http token to iframe - session

Hi I have an integration with KeycloakJS.
I'm able to login through redirect to keycloak webpage and have iframe to check for the token, also I'm able through http request to Keycloak with grant_type=password.
Is it possible once I login through HTTP request and get the token, to share the token to the Keycloak somehow, so when I refresh the page the iframe to be aware that I'm logged in, also when I go to keycloak website to be logged in there?

Related

Add a SSO flow to Laravel Passport

We are trying to implement a SSO solution using Laravel Passport. There is already a question about this topic but I think this one is more about the nitty-gritty.
Our requirements are:
A Laravel Passport service running on passport.com
Some first-party sites on various domains: foo.com, bar.com
Users can log in to foo.com and bar.com by typing their access details directly (Password Grant)
If a user logs in to foo.com and then they visit bar.com they should be automatically logged in
Based on my understanding of Oauth2, the system should work like the following:
Initial login flow:
The user types in their details on foo.com
foo.com makes a request to passport.com/oauth/token using a Password Grant and retrives an Access Token and a Refresh Token. Additionally, a SSO Token is generated and returned.
foo.com redirects the user to passport.com/sso/passthrough , passing the SSO Token and a return URL as query parameters.
passport.com saves the token as a cookie and then redirects to the return URL.
The user returns on foo.com and they can use the site
Note that the redirect to passport.com MUST take place, as otherwise browsers like Safari and Chrome in incognito will consider passport.com to be a third-party domain and the cookie will be blocked.
SSO flow:
The user visits bar.com
bar.com makes an AJAX request to passport.com/oauth/authorize using a SSO Grant and the redirect URI bar.com/sso/return
On passport.com, the SSO Grant looks for the SSO Token in the cookies and if the token is found, an authorization code is produced and sent bar.com/sso/return as a redirect. Because AJAX requests don't handle redirects, control passes directly to bar.com.
bar.com exchanges the authorization code for an access token and returns a successful AJAX response
bar.com receives the AJAX response and triggers a page refresh since the user is now logged in
For clarity, the SSO Token, SSO Grant, passport.com/sso/passthrough and bar.com/sso/return routes are not part of Laravel Passport; they are new concepts that we are implementing here.
The questions here are:
This flow looks to me like it should work. Am I missing anything?
Does this introduce any vulnerability into the Oauth2 flow? The Access Token and Refresh Token are never displayed to the client, but the SSO Token is. If an attacker steals it, I'm guessing they could potentially impersonate the user.
The Oauth2 protocol and Laravel Passport are stateless. By adding a cookie we are adding state. Is this a necessary evil or can it be done in a different way?
Should the SSO Token be saved to the cookie directly or should there be a different kind of token or authorization code there?
Any tips for implementing the SSO Grant and SSO Token?

Is it possible to logout from wso2is from my backend?

Are there another ways of doing logout without redirecting my Frontend to oidc/logout page (it works fine,but isn't it insecure sending idToken and my IDP url to frontend),i have separate front and back end. Like in Keycloak which invalidates session by sending refreshToken? If not,what is a right way of doing logout in my application?
We are sending the ID_Token in POST request directly to the IS Server thus it should not have any security concerns. Using ID_Token as id_token_hint while doing a logout is coming from OIDC specification[1]. This will prevent attackers from logging out users from their accounts because only the real RP can present the valid ID Token.
If you want an alternate way to logout you can make use of session management API[2]. But it is recommended to use the logout endpoint.
[1]https://openid.net/specs/openid-connect-session-1_0.html#RPLogout
[2]https://is.docs.wso2.com/en/5.9.0/develop/session-mgt-rest-api/

Logout with Spring Security and Keycloak OpenID Connect doesn't work

I am maintaining this application which is set up with:
an AngularJS front end
a Spring back end (with Spring Security, configured as per the Keycloak documentation) running on Tomcat
Keycloak as single sign-on solution using OpenID Connect.
The Implicit Flow is implemented like this:
The user navigates to the web app in their browser
The AngularJS web app checks if a (non-expired) JWT token is present in the Session Storage
If not, it redirects to Keycloak to request a token
Keycloak authenticates the user and redirects back to the webapp with the token
The web app stores the token in the Session Storage
Any request the web app makes to the back end API, it inserts the header Authorization: Bearer <token>
So far, so good. However, I noticed that logging out does not work as expected:
The user clicks the logout button in the web app
The web app deletes the token from the Session Storage
The web app redirects to the Keycloak logout endpoint
The user accesses the back end API directly and succeeds!
The reason is that a JSESSIONID cookie is stored and this also authorizes the user to access the API.
My questions:
Why is a JSESSIONID cookie being created? Is it default behaviour of Spring Security? Or did I misconfigure something?
How should I fix the logout issue? Make sure a JSESSIONID cookie is never created? Or implement a logout endpoint in the backend that deletes the session cookie?
NB: I am aware of
the risks of storing credentials in Session Storage;
the Implicit Flow being deprecated.

How to make OAuth2/Zuul redirect user to login page when refresh token expires?

How does one makes spring/zuul proxy redirect to the OAuth2 authentication endpoint when the refresh token has expired?
Currently what happens is that I get a BadCredentialsException in OAuth2TokenRelayFilter:getAccessToken() because the refresh token has expired and that gets returned as a HTTP 500 to the browser.
Architecture
edge service with #EnableZuulProxy, #EnableOAuth2Sso performs authentication with Keycloak and proxy calls to the services below
UI service that serves the user interface, not protected
main service with #EnableResourceServer, expects OAuth2 access token
Current implementation status
Requesting any Zuul proxy endpoint triggers the authentiation and redirect the browser to Keycloak. Upon successful authentication Keycloak redirect back to the proxy which retrieve both access token and refresh tokens. Then Zuul fulfils the initial endpoint call.
When the access token expires, a new token is retrieved using the refresh token before proxying to services.
In the main service the OAuth2 token is validated before processing API requests.
Everything works apart from that "refresh token expired" condition. This is such a standard case that I must be missing something obvious.

OAuth2 Implicit flow vs 'Traditional' session based auth for small SPA

Some background:
I am writing a small SPA that will use a back end that I have also written. The JS and the back end API are on the same server.
i.e. SPA will load from foo.com, back end is at foo.com/api
In the past I have always used Spring Security with simple form based login. After logging in the user will get a session cookie. Pretty standard stuff.
For this app I looked into OAuth2 implicit flow. My understanding is the User would load my page, then from the SPA I would direct the user to the authorization endpoint so my app could get a token. The user would be redirected from the authorization endpoint to a login form. After the user authenticated with the form.. they would be redirected back to the authorization endpoint to get the token and possibly grant access to the JS client. After that the user would be redirected to a URL specified by the client, with the new access token as a URL fragment.
I have this working and its all great. The part I don't quite get is this:
When the user is redirected to the login form and they authenticate a session is created on the server that has to at least last long enough for the user to be redirected to the authorization endpoint to get the token. At that point they already have an authenticated session on my server, why not just stop there and use traditional cookie and session based logins?

Resources