Giter VIP home page Giter VIP logo

idp-wizard's Introduction

πŸš€ Try it for free in the Phase Two Enhanced Keycloak as a service.

Identity Provider and Directory Sync setup wizards for Keycloak

Phase Two SSO and Directory Sync setup wizards for on-prem onboarding and enterprise SaaS self-management. This application uses the Keycloak Admin API and the Phase Two Organizations API to provide wizards for onboarding customer Identity Providers. The goal of these wizards is to solve the complex and error-prone process of connecting a vendor identity system a bit easier, and to avoid exposing customers to the Keycloak UI.

In addition to providing support for Identity Providers using OIDC and SAML, the wizards also supports Directory Synchronization protocols (aka "User Federation" in Keycloak) such as LDAP.

youtube-video-gif

Quick start

The easiest way to get started is our Docker image. Documentation and examples for using it are in the phasetwo-containers repo. The most recent version of this extension is included.

Configuration

There are some reasonable defaults used for the configuration, but the behavior of the wizards depends on a few variables, stored as Realm attributes.

Realm attribute key Default Description
_providerConfig.wizard.apiMode onprem onprem or cloud. onprem uses the Keycloak Admin APIs to set up an Identity Provider, so the user must have the correct realm-management roles. cloud uses the Phase Two Organizations API, so the user must have membership in an organization with the correct organization roles. A "picker" will be shown to the user if they have both and/or roles in more than one organization.
_providerConfig.wizard.emailAsUsername false When building Identity Provider mappers, should the IdP email address be mapped to the Keycloak username field.
_providerConfig.wizard.enableDashboard true Show a minimal dashboard showing the state of the setup.
_providerConfig.wizard.enableDirectorySync true Show Directory Sync section.
_providerConfig.wizard.enableGroupMapping true Currently does nothing.
_providerConfig.wizard.enableIdentityProvider true Show Identity Provider section.
_providerConfig.wizard.enableLdap true Allow LDAP config.
_providerConfig.wizard.enableScim true Allow SCIM config. (not currently used)
_providerConfig.wizard.trustEmail false Toggle trust email in the IdP config.
_providerConfig.assets.logo.url none URL for logo override. Inherited from keycloak-orgs config so we can use the same logo.

Building and installing

This uses the frontend-maven-plugin to build UI code and then packages it as a jar file that can be installed as an extension in Keycloak. Checkout this project and run mvn package, which will produce a jar in the target/ directory. Place the jar in the providers dir of your Keycloak distribution.

Dependencies

This extension depends on 2 other extensions. You must install all of the jars of the other extensions for this to function properly. Please see the documentation in those repos for installation instructions.

Compatibility

Although it has been developed and working since Keycloak 14.0.0, the extensions are currently known to work with Keycloak > 23.0.0. Additionally, because of the fast pace of breaking changes since Keycloak "X" (Quarkus version), we don't make any guarantee that this will work with any version other than it is packaged with in the Docker image.

Vendors

Wizards are currently available for the following vendors.

Vendor SAML OIDC LDAP SCIM Other
ADFS βœ… βœ…
AWS βœ…
Auth0 βœ… βœ…
Azure βœ…
Duo βœ…
Generic βœ… βœ… βœ…
Google βœ…
JumpCloud βœ…
Okta βœ… βœ… βœ…
OneLogin βœ…
PingOne βœ…

Contributing

πŸ’° πŸ’΅ A $250US bounty will be paid for each complete and accepted vendor wizard that has been labeled with bounty. Please file a PR with your implementation and reference the issue to be considered for the bounty. Acceptance of PRs is at the sole discretion of Phase Two, Inc.

Note: By submitting any code, documentation, or other materials submitted to this repository by pull request, you are immediately granting Phase Two, Inc. the copyright and an exclusive, perpetual, unlimited license to use it in this and any derivative works.

Working with the code

Run the latest version of the Phase Two enhanced Keycloak distribution:

docker run --name phasetwo_test --rm -p 8080:8081 \
    -e KEYCLOAK_ADMIN=admin \
    -e KEYCLOAK_ADMIN_PASSWORD=admin \
    -e KC_HTTP_RELATIVE_PATH=/auth \
    quay.io/phasetwo/phasetwo-keycloak:latest \
    start-dev \
    --spi-email-template-provider=freemarker-plus-mustache \
    --spi-email-template-freemarker-plus-mustache-enabled=true

Create a Realm, and in the idp-wizard Client configuration, update redirect URI for localhost:8080. Download the Client's keycloak.json and put it in src/keycloak.json.

Start the idp-wizard:

git clone https://github.com/p2-inc/idp-wizard
cd idp-wizard
yarn install --force && yarn start:dev

License

The extensions herein are used in the Phase Two cloud offering, and are released here as part of its commitment to making its core extensions open source. Please consult the license for information regarding use.

We’ve changed the license of our core extensions from the AGPL v3 to the Elastic License v2.


All other documentation, source code and other files in this repository are Copyright 2024 Phase Two, Inc.

idp-wizard's People

Contributors

jeffpatzer avatar xgp avatar bakmarcin avatar pnzrr avatar red-patience avatar

Stargazers

Raul Domingues avatar Timo KΓΌhne avatar Bill avatar Shahar Glazner avatar

Watchers

 avatar Shahar Glazner avatar  avatar

Forkers

getvoicify

idp-wizard's Issues

Style updates

https://docs.microsoft.com/en-us/style-guide/procedures-instructions/formatting-text-in-instructions

https://docs.microsoft.com/en-us/style-guide/procedures-instructions/describing-interactions-with-ui

From Jessica at Plotly

  • You can trim your copy a lot by getting rid of quotation marks around UI elements, bolding them instead, and omitting the type of element (ex. "button")
  • Some good pointers about which verbs to use in order to be clear, consistent, and inclusive. You'll find Google docs still say "click," but that's because they're behind. πŸ™‚ I noticed you have "select" in most places but a couple instances of "click".

Refactor Keycloak and Phase Two API Calls

Placeholder for how we are going to call Keycloak and Phase Two APIs from a single class/object.

Goals:

  1. Reduce cut-n-paste in the code
  2. Make it so we can easily replace the URL paths with the org url for future multi-org
  3. Make convenience methods so that calling the API does not require knowing the full request object (e.g. just the attribute.name and user.attribute for calling the /mappers endpoint)

useParams doesn't work in the dashboard

per @jeffpatzer the useParams hook isn't working when I try to call it from useKeycloakAdminApi when rendering the dashboard. we need this so we can get access to the realm in the path. E.g.

import KcAdminClient from "@keycloak/keycloak-admin-client";
import keycloak from "src/keycloak";
import { useParams } from "react-router-dom";

export const useKeycloakAdminApi = () => {
  let { realm } = useParams();
  
  const getServerUrl = () => {
    if (typeof keycloak.authServerUrl !== "undefined") {
      var u = keycloak.authServerUrl;
      if (u.charAt(u.length - 1) == "/") {
        u = u.substring(0, u.length - 1);
      }
      return u;
    } else {
      return undefined;
    }
  };

  const getRealm = () => {
    console.log("getRealm", realm);
    return realm;
  };

  const getAuthRealm = () => {
    if (typeof keycloak.realm !== "undefined") {
      return keycloak.realm;
    } else {
      return undefined;
    }
  };

  const settings = {
    baseUrl: getServerUrl(),
    realmName: getRealm(),
  };

  const kcAdminClient = new KcAdminClient(settings);

  const setKcAdminClientAccessToken = async () => {
    kcAdminClient.setAccessToken(keycloak.token!);
  };

  // Should be able to initiate off the bat and still provide as a callback
  setKcAdminClientAccessToken();

  return [
    kcAdminClient,
    setKcAdminClientAccessToken,
    getServerUrl,
    getRealm,
    getAuthRealm,
  ] as const;
};

Summary box on Dashboard needs stat updates

User, login stats

On-prem:

  • Active sessions: count from sessions
  • Offline sessions: count from sessions
  • Logins Today: count from events table
  • Logins This Week: count from events table
  • Users: all enabled users in this realm
  • Failed Logins: count from events table
  • Users Locked Out: tbd

Multi-organization

  • Active sessions: count from sessions, filter by members of org
  • Offline sessions: count from sessions, filter by members of org
  • Logins Today: count from events table, filter by members of org
  • Logins This Week: count from events table, filter by members of org
  • Users: all enabled users who are members of this org
  • Failed Logins: count from events table, filter by members of org
  • Users Locked Out: tbd

demo.phasetwo.io should be replaced with current hostname

There are several places where we use demo.phasetwo.io. This should be replaced with the current hostname. This value may change in the future, so we should have a helper function that returns the current hostname, but might change to a different/configurable value.

Email as username flag

add an emailAsUsername flag

  1. would cause a conditional mapper to appear on the mappers pages
  2. would change the default keycloak mappers to set the remote idp email address to the keycloak username

Connection status should show all IdPs

Connection Status portlet on dashboard should show list of configured IdPs, with the active one on the top. Color (green, yellow) to differentiate status.

Okta LDAP no longer does auto-fill

We used to auto fill the form fields in step 1 based on user input of "LDAP Host". it doesn't work anymore. Possible to bring it back?

Remove flash required when checking role

If someone doesn't have the right role, make sure that the page doesn't flash, but shows a loader until the access is cleared. Really only and issue on a first page load.

Save generated Alias on reload

The alias key gets regenerated whenever the component is reloaded. It needs to make sure it only gets generated once for that account and that it doesn't change.

No additional wizard state needs to be saved at the moment.

SAML IdP default config vars

When creating the IdP using the new IdP method, default values for config vars should be used if they were not present in the metadata url/file imports.

  ...
  config: {
    ...
    nameIDPolicyFormat: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
    principalType: "SUBJECT",
    ....
  }
  ...

This definitely is needed for Azure SAML, but probably is true of others.

Feature flags

We need a mechanism to tell the wizard that certain features are on/off, and have certain enums/modes set.

  1. the backend will serve a json file with a feature:value hash. this will be on a per realm basis. /auth/realms//wizard/config.json
  2. the frontend will fetch this file when it loads and make it available (as a hook?). the utility that loads it should have fallback values for each expected flag

Current flags:

  • groupMapping: true/false. whether group mapping steps should be displayed in the wizards and the group mappers should be created when calling the api
  • apiMode: cloud/onprem. which APIs to use
  • enableLdap: true/false. allow LDAP wizards (this is related to apiMode, but might change in the future, so adding it separately)
  • enableDashboard: true/false. whether or not to show the dashboard and link

Okta Saml Wizard

Update and refactor to new formats to use correct validations and forms

mode for org portal or admin setup

We need to have a mode that allows the use of the wizards by two agents, 1. keycloak admins (kcadmin), and 2. organization admins (orgadmin)

The mode will dictate the URLs that are used for the API requests.

How do we differentiate between modes

  • Can we serve a json doc that indicates the mode, config params, feature flags? See #83

What API methods are used for each mode

  • For kcadmin, APIs used are as currently written
  • For orgadmin, APIs are documented here http://phasetwo.io/api/ (specifically see the Identity Providers section)

What are the feature flags

  • For orgadmin, we currently need a way to turn off any LDAP IdPs
  • We want to conditionally enable the Dashboard
  • API realm (currently indicated by the realm in the url)
  • Authentication realm (currently indicated by the keycloak.json file, which is dynamically served for each realm

Azure SAML default mappers

The following mappers need to be created following the creation of the IdP. (using the POST /realms/{realm}/identity-provider/instances/{idp-alias}/mappers endpoint)

email

{"identityProviderAlias":"azure-saml","config":{"syncMode":"INHERIT","attributes":"[]","attribute.name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress","user.attribute":"email"},"name":"email","identityProviderMapper":"saml-user-attribute-idp-mapper"}

firstName

{"identityProviderAlias":"azure-saml","config":{"syncMode":"INHERIT","attributes":"[]","attribute.name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname","user.attribute":"firstName"},"name":"firstName","identityProviderMapper":"saml-user-attribute-idp-mapper"}

lastName

{"identityProviderAlias":"azure-saml","config":{"syncMode":"INHERIT","attributes":"[]","are.attribute.values.regex":"","attribute.name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname","user.attribute":"lastName"},"name":"lastName","identityProviderMapper":"saml-user-attribute-idp-mapper"}

username

{"identityProviderAlias":"azure-saml","config":{"syncMode":"INHERIT","attributes":"[]","attribute.name":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name","user.attribute":"username"},"name":"username","identityProviderMapper":"saml-user-attribute-idp-mapper"}

Confirmation screen for `cloud` mode

The confirmation screen needs some modification when we are in cloud mode:

  1. User won't know about "Keycloak", so the button should say "Create Identity Provider"
  2. Following successful creation, there should be no link back to the Keycloak Admin UI

WIP: Group mapping step

Need to add group mapping step for all the wizards

TODO:

  • @xgp specs
  • @jeffpatzer Update the wizards to conditionally show the step based on the groupMapping feature flag
  • @xgp show a prototype of how to add a group mapper to the default IdP mappers we create with the API
  • @jeffpatzer add the group mapper to the default API calls when the IdP is created. enabled if the groupMapping feature flag is true

On successful creation of IdP, provide Keycloak admin link

Once an IdP is successfully created on the confirmation page, provide a link "Manage {idp friendly name} in Keycloak" with the format: https://{host}/auth/admin/{realm}/console/#/realms/{realm}/identity-provider-settings/provider/{"oidc"|"saml"}/{alias}

Remove json from events table

Filter by members of org (if applicable)

Show only username/email

Json popup from detail link

Allowed Events:

  • VERIFY_EMAIL
  • VERIFY_EMAIL_ERROR
  • CUSTOM_REQUIRED_ACTION
  • CUSTOM_REQUIRED_ACTION_ERROR
  • DELETE_ACCOUNT
  • DELETE_ACCOUNT_ERROR
  • LOGIN
  • LOGIN_ERROR
  • LOGOUT
  • LOGOUT_ERROR
  • REGISTER
  • REGISTER_ERROR
  • RESET_PASSWORD
  • RESET_PASSWORD_ERROR
  • UPDATE_CONSENT
  • UPDATE_CONSENT_ERROR
  • UPDATE_EMAIL
  • UPDATE_EMAIL_ERROR
  • UPDATE_PASSWORD
  • UPDATE_PASSWORD_ERROR
  • UPDATE_PROFILE
  • UPDATE_PROFILE_ERROR
  • VERIFY_EMAIL
  • VERIFY_EMAIL_ERROR
  • VERIFY_PROFILE
  • VERIFY_PROFILE_ERROR

Admin Portal (aka organization dashboard v2)

Wizards for kcadmin (on-prem or keycloak administrator use case) is fine as-is, and doesn't need a dashboard.

For orgadmin (inter-realm organization administrator), they need a place to administer their org and setup IdPs

This is basically the new organizations section of the keycloak-admin-ui (without the ability to create new orgs) plus the ability to launch the wizards.

idp selector should be homepage

default entry point for /auth/realms/foo/wizard should be the idp selector. dashboard should still be accessible and linked, but under a different path (e.g. /auth/realms/foo/wizard/dashboard)

Reset alias after a successful creation in Keycloak

At the end of the confirmation step, if the creation of the IdP and Mappers in Keycloak is successful, clear the alias from state/storage.

This is useful because the user may want to create another IdP of the same type.

Test page for testing login after `cloud` confirmation

  1. Alias of the created identity provider will be different than the submitted value. This must be taken from the Location header of the successful creation of an idp and used when creating the mappers. The Location header will be a full URL. The alias will be a UUID at the last segment, following the last /.
  2. There should be a description of how to try the completed idp. Something like "Test the identity provider (this will log you out of the wizard, or you can open it in an incognito window)". This should be a normal realm login link with prompt=login and kc_idp_hint=<alias>

Generic protocols missing base url path in selector

In the IdP selector screen, the 3 generic protocols do not use the base path in their links. E.g. from a selector screen with url

https://keycloak-xgp.ddns.net/auth/realms/demo/wizard/idp

The generic SAML protocol should link

https://keycloak-xgp.ddns.net/auth/realms/demo/wizard/idp/saml/saml

but currently links

https://keycloak-xgp.ddns.net/idp/saml/saml

Redo IdP logos

I stole these, and they're not the official ones anyway.

  • G SAML should be just G, Google or Google Workspace
  • ADFS should be Active Directory (because we'll support FS and DS)
  • etc

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.