Keycloak with Okta IDP Initiated SSO Login

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:

  1. User logs into Okta.
  2. Gets to Okta app screen.
  3. Clicks on an app link.
  4. App redirects to Keycloak for authentication.
  5. Keycloak redirects automatically to Okta.
  6. Okta sees the user is already logged in.
  7. Redirects back to Keycloak.
  8. Creates SAML assertion.
  9. 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:

  1. Create an app in Okta.
  2. Export Okta metadata.
  3. Create a new Keycloak Identity Provider by using Okta metadata (import a file).
  4. Export Keycloak metadata for the Identity Provider (Identity Provider > okta > Export > Download).
  5. Create a new Keycloak client by using Identity Provider metadata (import a file).
  6. Change Assertion Consumer Service POST Binding URL to your application URL.
  7. Change IDP Initiated SSO Relay State to your application URL.
  8. 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:

  1. Application URL: https://example.com/lisenet
  2. Keycloak URL: https://example.com/auth
  3. Keycloak realm: lisenet
  4. Keycloak Identity Provider alias: okta
  5. 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:

  1. Add execution Create User if Unique.
  2. 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:

  1. Client ID: https://example.com/auth/realms/lisenet (this should be created automatically)
  2. IDP Initiated SSO URL Name: myapp-saml
  3. IDP Initiated SSO Relay State: https://example.com/lisenet
  4. 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

18 thoughts on “Keycloak with Okta IDP Initiated SSO Login

  1. 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.

  2. 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?

  3. 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)

    • 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.

  4. 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

  5. Just wanted to say this documentation is just as bad as the documentation provided by Keycloak – completely awful

Leave a Reply to Rasmi Ranjan Muduli Cancel reply

Your email address will not be published. Required fields are marked *