[keycloak-user] Fwd: Multi-org salesforce with single realm keycloak

Anthony Fryer anthony.fryer at gmail.com
Fri Jun 10 22:15:44 EDT 2016


You can implement a dynamic keycloak config resolver that can work with
realms not known in advance.  I've just been doing exactly the same thing.
My requirement was to use the host name to identify a realm, so
tenanta.mydomain.com/my-client would use realm "tenanta",
tenantb.mydomain.com/my-client would use "tenantb" etc and realms could be
created dynamically and my-client would immediately work with those new
realms without requiring a reboot or re-configuration.   There are
different KeycloakConfigResolver implementations you can use to do this,
depending on your client configuration.

If the client is configured as public (no client secret) or if the client
secret for the application is the same in each realm, then you can use a
keycloak template for configuration.  So you could deploy a
WEB-INF/keycloak-template.json file which looks something like this...
{

  "realm": "tenantA",  "realm-public-key":
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA07H+1raA8G5lU9II9GwQ1r2yXzSeBpEC6Lz822iB+oZGi36KC6caVOyi1IVIWB/ZnxxoC8AHsn4ASYJnYUMNTjRvK9nwHCP825LD3nHFBHyQ0gUHBELRi6ZvmOu3TnyiIlnR2SCxwmND5ifgtDfKwldcdCTNWqJG5MkcOimhDEiZYLOrShH5pCcEkPE5JBj0GDGYs9AcUT8/OrJEvInVAfnMMxvzZfXhJQlXnq0HbkGPNL2LMq66bmfI7OTzWKpIIoa24DOcxvu5FEqnnfhEZ+RkhfrVVe876T7Jx9f128xOTAYgi98515+xeFGei1Qer1IJCtnE5vICKKVtDdJg1wIDAQAB",
 "auth-server-url": "https://keycloak.mydomain.com/auth",
"ssl-required": "none",  "resource": "my-client",  "public-client":
true}


The KeycloakConfigResolver would use this template for each realm and just
overwrite the "realm" and "realm-public-key" values with the real values.
To get those real values, the KeycloakConfigResolver would first work out
the realm name.  In my case, I derive the realm name from the hostname, so
tenanta.mydomain.com would indicate "tenanta" was being used.  Once you
have derived the realm name, then you can do a http get request to
http://<keycloak_url>/auth/realms/<tenantname>
(eg. https://keycloak.mydomain.com/auth/realms/tenanta).  This endpoint
isn't secured and returns something similar to the following...

{

   - realm: "tenantA",
   - public_key:
   "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA07H+1raA8G5lU9II9GwQ1r2yXzSeBpEC6Lz822iB+oZGi36KC6caVOyi1IVIWB/ZnxxoC8AHsn4ASYJnYUMNTjRvK9nwHCP825LD3nHFBHyQ0gUHBELRi6ZvmOu3TnyiIlnR2SCxwmND5ifgtDfKwldcdCTNWqJG5MkcOimhDEiZYLOrShH5pCcEkPE5JBj0GDGYs9AcUT8/OrJEvInVAfnMMxvzZfXhJQlXnq0HbkGPNL2LMq66bmfI7OTzWKpIIoa24DOcxvu5FEqnnfhEZ+RkhfrVVe876T7Jx9f128xOTAYgi98515+xeFGei1Qer1IJCtnE5vICKKVtDdJg1wIDAQAB"
   ,
   - token-service: "
   https://keycloak.mydomain.com/auth/realms/tenantA/protocol/openid-connect
   <https://keycloak.cyberavenue.com.au/auth/realms/tenantA/protocol/openid-connect>
   ",
   - account-service: "
   https://keycloak.mydomain.com/auth/realms/tenantA/account
   <https://keycloak.cyberavenue.com.au/auth/realms/tenantA/account>",
   - admin-api: "https://keycloak.mydomain.com/auth/admin
   <https://keycloak.cyberavenue.com.au/auth/admin>",
   - tokens-not-before: 0

}

The KeycloakConfigResolver then uses the "realm" and "public_key" values
from that response, overrides the values from the keycloak-template.json
file to create the KeycloakDeployment (using KeycloakDeploymentBuilder).

If your client isn't public and the client-secret differs and isn't known
in advance, then this solution wouldn't work.  In that case, another
solution can be used which is slightly more complicated.  The idea is the
KeycloakConfigResolver does the following...

1/ Get a token for the admin-cli client in the "master" realm.  This may
require configuring a username and password that can be used used to obtain
this token.
2/ Use the rest api to get a list of clients in the requested realm (ie.
http get to http://<keycloak_url>/auth/admin/realms/{realm}/clients using a
Bearer token obtained from step 1
3/ Iterate through the list and find the Client you're interested in (ie.
client.getClientId().equals("my-client") ).  You need the client UID
identifier from this.
4/ Use the rest api to get the keycloak deployment installation file by
doing a GET to http://<keycloak_url>/auth/admin/realms/{realm}/clients/{client-uid}/installation/providers/keycloak-oidc-keycloak-json,
using the Bearer token from step 1 and the client UID from step 3.  Then
use KeycloakDeploymentBuilder on the response body returned from this
service.



Regards,

Anthony


On 04:43, Sat, 11/06/2016 Jesse Chahal <jessec at stytch.com> wrote:

> The keycloak config resolver works well when all realms are known in
> advance. I was trying to imply in my diagram that all realms are not
> known in advance as realms are going to be created for new customers
> on demand. Doing a new production deployment whenever a SaaS product
> has a new customer added is not a feasible solution.
>
> On Wed, Jun 8, 2016 at 7:01 PM, Anthony Fryer <anthony.fryer at gmail.com>
> wrote:
> > Why do you say "very hard to get App1 to support multiple realms (no
> adapter
> > or keycloak support)"?
> >
> > Keycloak does provide multi-tenancy support via the
> KeycloakConfigResolver.
> > See
> https://github.com/keycloak/keycloak/tree/master/examples/multi-tenant.
> >
> > The issue would be if your app can't use a keycloak adapter.
> >
> > On Thu, Jun 9, 2016 at 10:05 AM, Jesse Chahal <jessec at stytch.com> wrote:
> >>
> >> Hi,
> >>
> >> I'm back again. I'm trying to figure out how scale Identity Providers.
> >> We are planning on trying to integrate our App1 with salesforce. A
> >> user who logs into salesforce should be able to have a native feel of
> >> our App1 within it. Todo this we'll probably have to end up building
> >> salesforce native apps. For every salesforce organization/licensee we
> >> will have to register an Identity provider with keycloak to make sure
> >> they can correctly use App1. Some configuration options we came up
> >> with are listed below. Has anyone else solved a similar problem?
> >>
> >> OPTION 1
> >> ########################################################
> >> # Keycloak
> >>                               #
> >> # ---> master realm
> >>                           #
> >> # ---> realm 1
> >>                               #
> >> # --- ---> app1_client (open ID)
> >>                      #
> >> # --- ---> salesforce_org1_saml2.0_identity_provider
> >> #
> >> # --- ---> salesforce_org2_saml2.0_identity_provider
> >> #
> >> #
> >>                                      #
> >> # Salesforce
> >>                               #
> >> # ---> org1
> >>                                 #
> >> # ---- ----> salesforce_appX (uses App1)
> >>               #
> >> # ---> org 2
> >>                                 #
> >> # ---- ----> salesforce_appX (uses App1)
> >>               #
> >> # ---- ----> salesforce_appY (uses App1)
> >>               #
> >> # .....
> >>                                      #
> >> #
> >>                                      #
> >> # App 1
> >>                                  #
> >> # ---> OpenID to realm1 (using adapter)
> >>               #
> >> ########################################################
> >> benefits
> >> - single login page
> >> - single realm
> >> cons
> >> - login page with infinite number of identity provider buttons present
> >>
> >>
> >> OPTION 2
> >> ########################################################
> >> # Keycloak
> >>                               #
> >> # ---> master realm
> >>                           #
> >> # ---> realm 1
> >>                               #
> >> # --- ---> app1_client (open ID)
> >>                      #
> >> # --- ---> salesforce_org1_saml2.0_identity_provider
> >> #
> >> # ---> realm 2
> >>                               #
> >> # --- ---> app1_client (open ID)
> >>                      #
> >> # --- ---> salesforce_org2_saml2.0_identity_provider
> >> #
> >> #
> >>                                      #
> >> # Salesforce
> >>                               #
> >> # ---> org1
> >>                                 #
> >> # ---- ----> salesforce_appX (uses App1)
> >>               #
> >> # ---> org 2
> >>                                 #
> >> # ---- ----> salesforce_appX (uses App1)
> >>               #
> >> # ---- ----> salesforce_appY (uses App1)
> >>               #
> >> # .....
> >>                                      #
> >> #
> >>                                      #
> >> # App 1
> >>                                  #
> >> # ---> OpenID to realm1, realm2, realm#.... (using adapter)
> >> #
> >> ########################################################
> >> benefits
> >> - single salesforce button per login page
> >> - users are more isolated in single realm
> >> cons
> >> - very hard to get App1 to support multiple realms (no adapter or
> >> keycloak support)
> >> _______________________________________________
> >> keycloak-user mailing list
> >> keycloak-user at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/keycloak-user
> >
> >
> >
> >
> > _______________________________________________
> > keycloak-user mailing list
> > keycloak-user at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/keycloak-user
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-user/attachments/20160611/27c431e8/attachment-0001.html 


More information about the keycloak-user mailing list