It is possible to set up an IDP Initiated Login for a client from an external IDP.
Well this has been a real adventure.
The Problem
This is what I was trying to achieve:
- User logs into Okta.
- Gets to Okta app screen.
- Clicks on an app link.
- App redirects to Keycloak for authentication.
- Keycloak redirects automatically to Okta.
- Okta sees the user is already logged in.
- Redirects back to Keycloak.
- Creates SAML assertion.
- Redirects back to the app.
Keep in mind that I’m not a SAML expert, therefore this might not be entirely correct.
This is what worked in the end using Keycloak 11.0:
- Create an app in Okta.
- Export Okta metadata.
- Create a new Keycloak Identity Provider by using Okta metadata (import a file).
- Export Keycloak metadata for the Identity Provider (Identity Provider > okta > Export > Download).
- Create a new Keycloak client by using Identity Provider metadata (import a file).
- Change Assertion Consumer Service POST Binding URL to your application URL.
- Change IDP Initiated SSO Relay State to your application URL.
- Set IDP Initiated SSO URL Name to “myapp-saml” (this is what I chose to use).
Application Details
For the sake of simplicity, I’m going to use the following URLs in this article:
- Application URL: https://example.com/lisenet
- Keycloak URL: https://example.com/auth
- Keycloak realm: lisenet
- Keycloak Identity Provider alias: okta
- IDP Initiated SSO URL Name: myapp-saml
1. Configure Okta App
Create an app in Okta and use details similar to the following:
Single Sign On URL:
root/auth/realms/{broker-realm}/broker/{idp-name}/endpoint/clients/{client-id}
In our case the URL looks like this:
Single Sign On URL: https://example.com/auth/realms/lisenet/broker/okta/endpoint/clients/myapp-saml
Also set the following:
Audience Restriction: https://example.com/auth/realms/lisenet
At this stage the Single Sign On URL is not going to work because we have not configured Keycloak yet. But we already know what the URL will look like.
Download Okta metadata and save it as okta-metadata.xml
. Note the Identity Provider SSO URL, it will look something like that (this isn’t a valid URL):
https://lisenet.okta.com/app/lisenetorg203009_lisenet_1/ekkgje4ihwL1QqFSx4u4/sso/saml
That’s how you get to your application.
2. Configure Keycloak Identity Provider
2.1 Authentication Flow
Create a new authentication flow for SAML. Log into Keycloak, navigate to Authentication > New.
Set Alias to SAML_First_Broker. Leave Top level flow type as generic.
Add executions to SAML_First_Broker flow:
- Add execution Create User if Unique.
- Add execution Automatically Set Existing User.
Set requirements to both the executions to ALTERNATIVE.
2.2 Identity Provider
Navigate to Identity Provider and add a new user-definer SAML 2.0 provider. Set the alias to okta, import metadata from file okta-metadata.xml
and verify the Single Sign-On Service URL, it will look something like that (again, this isn’t a valid URL):
https://lisenet.okta.com/app/lisenetorg203009_lisenet_1/ekkgje4ihwL1QqFSx4u4/sso/saml
Set First Login Flow to SAML_First_Broker.
Set NameID Policy Format to Unspecified.
Save changes.
Click on the Export tab and download metadata (Identity Providers > okta > Export > Download), save it as kc-idp-metadata.xml
.
3. Configure Keycloak Client
Create a new Keycloak client by using Keycloak’s Identity Provider metadata file kc-idp-metadata.xml
.
Navigate to Clients > Create > Import (select metadata). This will populate the client config.
Configure the following, change values if they are already set:
- Client ID: https://example.com/auth/realms/lisenet (this should be created automatically)
- IDP Initiated SSO URL Name: myapp-saml
- IDP Initiated SSO Relay State: https://example.com/lisenet
- Assertion Consumer Service POST Binding URL: https://example.com/lisenet
Save changes. After this you can reference your client at the following URL:
https://example.com/auth/realms/lisenet/protocol/saml/clients/myapp-saml
Verify that the application is available. If this does not load the app login screen then you will have to debug. If this works, you can try logging in using Okta IDP Initiated SSO Login.
Note that the Relay State is the URL that users will be directed to after a successful authentication through SAML.
References
https://www.keycloak.org/docs/11.0/server_admin/#idp-initiated-login
http://keycloak-user.88327.x6.nabble.com/keycloak-user-Keycloak-amp-Okta-td2803.html
https://stackoverflow.com/questions/54785427/idp-initiated-sso-using-keycloak
https://issues.redhat.com/browse/KEYCLOAK-5976
https://support.okta.com/help/s/article/Common-SAML-Terms
how to make this idp initiated client as identity broker.
Hi, what have you tried so far?
Hi Tomas , we have followed the above steps and implemented idp intiated sso. But when redirecting back from IDP , Our keycloak is not able to process the saml response it thorws internal server error.
Hi, what’s your Keycloak config? What error do you get?
I can’t speak for him, but I’ve been trying the same thing and I get this error in Keycloak:
error=saml_token_not_found
Hi and thanks for a good blog post!
When trying this, it seems I get redirected to localhost with a POST request and I get “Cannot POST /” (it’s a pure javascript application so it isn’t listening for any specific HTTP verbs). I’m guessing this is due to rebinding the “POST binding”… does your application have something listening on that port?
I do not have this option:
Click on the Export tab and download metadata (Identity Providers > okta > Export > Download), save it as kc-idp-metadata.xml.
How do I export kc-idp-metadata.xml? Is it the same as Real Settings -> General -> Endpoints -> SAML 2.0 Identity Provider Metadata (this opens up a tab in your browser and I can save the data)
What version of Keycloak do you use?
I don’t see it either. Keycloak 15.0.2
I tested on Keycloak 11, do you want to try that version instead?
I have this issue after clicking on Okta button:
type=IDENTITY_PROVIDER_RESPONSE_ERROR, realmId=test, clientId=null, userId=null, ipAddress=10.85.189.160, error=invalid_saml_response, reason=invalid_destination
However this url works
https://example.com/auth/realms/test/protocol/saml/clients/myapp-saml
Which version of Keycloak are you on? I tested on 11.0.
I tested on keycloak 15.0.2
Can you try with Keycloak 11 and see if it works? If it does, then it will be something to do with Keycloak 15. It will narrow the scope of the problem down for you.
This issue is related to environment settings when load balancer is accessible via https but keycloak nodes by http. I fixed it via code modification in SAMLEndpoint.java (getExpectedDestination method).
I have only one question – why keycloak sends POST request to may app? My app is openid-connect client of keycloak and this client doesn’t expect any POST requests. The client login works fine in case keycloak calls okta but Initiated SSO Login requires additional development on client’s side to support POST.
Hi Team,
When i hit the URL “https://example.com/auth/realms/master/protocol/saml/clients/myapp-saml”, it takes me to the login page which asks username/password and also can see “okta” as an IDP hyperlink. When i click on “okta” hyper link it takes me to the url “https://dev-67676766.okta.com/app/dev-67676766_keycloak_1/exk67gw9x7Vw5Vtjd5d7/sso/saml”, Page loaded is okta login screen.
Is this is what expected from the configurations above. I am using keycloak version 18.0.2
Just wanted to say this documentation is just as bad as the documentation provided by Keycloak – completely awful
Thanks for your feedback, appreciated.
I’ve tried to replicate this – but wow are there steps missing and assumed
I set this up back in 2020 using Keycloak 11, it worked for me. Granted it’s been 4 years, it may not work, or require additional configuration, with other versions of Keycloak.You should use it as a reference point to get started rather than a complete step-by-step guide which it is not I’m afraid.
Thanks for this guide
I am trying it with v21
login from okta to “broker/okta/endpoint/clients/okta” is successful
but the redirect after this to “broker/okta/endpoint”
fails with “You are already logged in” instead of redirecting to url I configured in RelayState
Tried this configuration. Am getting error=invalid_redirect_uri in the keycloak.
Hopefully you don’t mind me posting this but I made a more updated guide, following a similar pattern to what you have here! Hope it helps any who come across this in 2024!
https://www.lumilinks.com/blog/idp-initiated-login-with-keycloak
Oh, cracking effort, thank you for the link Josh!