Skip to main content

· 4 min read

With many companies racing into the cloud, very little is written about the huge opportunity, and potential pitfalls of building software for on-prem and private cloud deployments. With the growing Kubernetes and CNCF ecosystems, the balance point to justify self-hosting is constantly shifting. This is great news for companies that must host data and applications inside the enterprise. For software vendors looking to serve this exploding market, authentication can be a blind spot.

A story, inspired by customer use cases:

You’ve built a successful enterprise SaaS product, and your cloud offering has taken off. Recently, you’ve been getting inquiries from government agencies, large companies in regulated industries, and foreign companies – all of which have legal, compliance or regulatory requirements that prohibit them from using your product in the cloud.

Given the size of the opportunity, you’ve decided to go for it. Your team has packaged your application up as a set of Kubernetes manifests, making changes, replacing cloud services with open source alternatives, and even built out a runbook to help your devops peers at the customer operate it themselves.

The big day comes, and you’re installing at your first customer. You expect that there will be some minor bumps along the way, but their first question just flattens you: “How do we connect this to our in-house identity provider?” It was a question that was never on your radar, but now it’s the most important thing for the customer.

Like most SaaS companies, you’re probably either hand-rolling your authentication and user management using something like Passport.js, Devise, Django, etc., using some social login options, or using a cloud-only service like Auth0 or WorkOS. If you had implemented SAML, the most common protocol for just-in-time user provisioning with enterprise identity providers, you probably went for a basic approach. You wrongly assumed that user management and identity brokering would be easier for on-prem.

You throw some engineering and customer success resources at the problem, but quickly realize it’s not a scalable solution. The customer wants to map their groups, and manage access and authorization through their IdP. Just the overhead of connecting to every possible type of IdP, and supporting that for every customer, will eat up your margin before they start using your application.

The good news is that you’re not alone in missing this key enterprise need. Many companies who are new to on-prem and private cloud deployments learn this the hard way, many without losing customers.

However, the reality is that for an application that is used by an entire enterprise, who can use it (authentication) and how (authorization) is equally as important for on-prem applications as cloud. And, being hosted and operated by your customer, simplicity of management and transparency is more important than cloud.

An open source solution to the rescue

Fortunately, there is feature complete identity and access management system that is equally at home both on-premise and in the cloud. It can easily facilitate identity brokering with the customer identity provider, as well as give their IT staff access to critical access and operational information.

At Phase Two, we’ve had a front row seat in solving this problem. Our customers have deployed Keycloak, bundled with their application to over 300 of their customer sites. In these deployments, Keycloak is used for identity brokering to the customer identity provider, SSO authentication for all of their deployed applications, and role and access management to broker and manage authorization within their applications.

Tools to empower the customer

In addition to solving these core challenges, Phase Two has built tools to extend enterprise use-cases and facilitate customer onboarding, one of the biggest drags on Customer Success hours, and ultimately a huge margin drain.

To this end, the most valuable tool, from our customers’ perspectives is our Identity Provider Setup Wizard. This tool is meant as a guide for customers’ initial IdP connection, turning an esoteric form into a clear step-by-step process for specific IDPs (what keys to get, where to store them, and so on). This had previously been the long pole in the onboarding tent. By giving the customers a tool to self-configure and manage their own IdP connection, Phase Two has gifted back valuable Customer Success hours and margin dollars.

idp-wizard-video-gif

We conveniently bundle all of these tools in Docker images for easy deployment.

Does the above story sound familiar, or something you might be stumbling into? Contact sales to find out how we can help your journey to on-prem be as painless as possible and supercharge your customer identity onboarding process.

· 6 min read

In today's digital landscape, managing user identities and securing access to applications and services is paramount for businesses of all sizes. As the demand for robust identity and access management (IAM) solutions grows, so does the market, with various commercial options vying for attention. When we first started using Keycloak over 7 years ago, we were surprised that there was a relatively unknown, but completely open-source alternative to commercial offerings in the Identity and Access Management market.

Commercial offerings

Companies such as Auth0, Okta, Microsoft (through AzureAD) had created cloud authentication services, and helped bring standardization to the market through implementation of standards, such as OIDC, SAML, SCIM, LDAP, etc. However, there was little differentiation among them, and despite their pricing models, were essentially commodities that were the same.

Amazon released AWS Cognito, which did price it as a commodity, but failed so miserably in UI and developer ergonomics, that it failed to reach a dominant market position despite its de minimis cost.

More recently, nascent companies such as WorkOS and Frontegg, while casting themselves as CIAM and “SSO made easy” to enterprise SaaS customers, are really just repackaging the same IAM features and protocol implementations that have been available in Keycloak for years. Furthermore, the pricing models have tilted back towards predatory on your company’s business model.

Open source alternatives

Amidst this landscape, open-source alternatives like Keycloak are emerging as powerful contenders, offering unique advantages over their commercial counterparts. Because the market has settled on standard protocols, it opened the door for superior open-source implementations to emerge with feature parity and standards compliance. Keycloak stands out as an alternative to commercial IAM solutions, enabling your business to unlock both flexibility and control.

  1. Open Source Foundation: At the heart of Keycloak lies its open-source nature. Developed by Red Hat, Keycloak provides a fully-fledged IAM solution that is freely available for anyone to use, modify, and extend according to their requirements. This open ethos empowers organizations with unparalleled flexibility and control over their identity infrastructure, without being tied to proprietary vendors or licensing agreements. Furthermore, given the core security requirements of the protocol implementations, developing in the open gives customers the reassurance that the code has been audited by others, unlike closed source, buggy, commercial implementations that come with zero transparency or guarantees.
  2. Cost-Effectiveness: One of the most significant advantages of Keycloak is its cost-effectiveness. Unlike commercial IAM solutions that operate on subscription-based pricing models, Keycloak eliminates licensing fees, enabling organizations to allocate resources more efficiently. With Keycloak, businesses can scale their identity infrastructure without worrying about escalating costs, making it an attractive option for startups, small businesses, and enterprises alike.
  3. Customization and Extensibility: Keycloak stands out for its robust customization and extensibility capabilities. From authentication flows and user federation to role-based access control (RBAC) and fine-grained permissions, Keycloak provides a plethora of features that can be tailored to suit specific use cases and compliance requirements. Moreover, its modular architecture and comprehensive API support facilitate seamless integration with existing systems and third-party services, empowering developers to build bespoke identity solutions with ease.
  4. On-Premise and Cloud Deployment: Whether organizations prefer on-premise deployment for enhanced security and compliance or cloud-based solutions for scalability and convenience, Keycloak offers the flexibility to meet diverse deployment needs. With support for Docker, Kubernetes, and other containerization technologies, Keycloak simplifies deployment across various environments, ensuring seamless integration into existing infrastructure and workflows.
  5. Active Community and Support: Backed by a vibrant community of developers and contributors, Keycloak benefits from ongoing enhancements, bug fixes, and feature additions. This active ecosystem fosters innovation and collaboration, with users sharing best practices, troubleshooting tips, and extensions through forums, mailing lists, and code repositories. Additionally, organizations seeking professional support and services can leverage expertise of a growing ecosystem of companies providing support, ensuring reliable deployment and ongoing maintenance of their Keycloak instances.

Barriers

So, given Keycloak's inherent advantages, while solving all of the same problems, why has it failed to receive broad market adoption? Looking back, and polling our customer base, it seems that Keycloak has suffered from a couple of barriers:

  1. Awareness: Other than a couple of markets (e.g. Germany) Keycloak is still relatively unknown. Because it’s not a commercial entity, there isn’t a content marketing engine that focuses on discovery for common use cases.
  2. Onboarding: Documentation for getting successful for common use cases is fragmented and often hard to find. When solving a new problem, examples are a great way to get a developer “hooked”, but these are largely missing from official Keycloak documentation.
  3. Community: Because the core Keycloak developers have largely been working for one customer (RedHat) and not the community at large, developers who are exploring Keycloak for the first time can find it hard to know where to ask question. While the Discourse, GitHub, Slack and mailing lists are a good direction, there’s not a definitive way to get support.
  4. UI: The Keycloak Admin UI, while complete, is intimidating to new users. Unlike the commercial alternatives, that have invested resources in building and measuring customer success into their UIs, while Keycloak’s attitude has been "RTFM". Furthermore, the user facing UIs of Keycloak are notoriously “rough edged”, commercial alternatives are beautiful, modern, and capable of easy customization and branding.

Obviously, we think that the barriers are something that can be solved, and Phase Two has been working hard in its open source extensions and cloud offerings to overcome these barriers. We've already made great strides, and believe that we're at the point where customers can realize the above advantages, while compromising relatively little -- All while achieving tremendous cost savings.

Migrating from your current identity provider

Already using one of the commercial systems? Keycloak is a complete, robust and mature identity solution that can replace your identity provider and user management systems today. It has complete parity with all of the major features of commercial IAM systems, and because of reliance on standards, migration is easier than you think. By migrating to Keycloak, you gain full control over your authentication and authorization processes, enabling seamless integration, customization, and scalability tailored to your organization's unique needs. 

Phase two has implemented user migration support in the product for all tiers. This is meant to ease your transition from your existing user management system so that migration can occur incrementally with a complete fallback plan. For Premium and Enterprise subscribers, we include migration support. Contact sales to get started with your migration.

Conclusion

In a landscape dominated by commercial IAM solutions, Keycloak shines as a compelling alternative that combines the power of open source with enterprise-grade features and flexibility. With its cost-effectiveness, customization capabilities, deployment flexibility, and active community support, Keycloak empowers organizations to take control of their identity infrastructure, unlock new possibilities, and adapt to evolving security and compliance requirements. Whether you're a startup looking to bootstrap your identity management or an enterprise seeking to streamline operations, Keycloak offers a compelling solution that puts you in the driver's seat of your IAM journey.

· 6 min read

Keycloak has been a leader in the Identity and Access Management (IAM) world since its launch almost 9 years ago. The market for IAM tools had several commercial offerings that failed to meet many business model and price needs, and Keycloak filled the hole with an open-source offering.

Fast-forward to today, Keycloak still leads with mature protocol implementations, hardened security, and a reliable architecture that has been battle-tested for years, under the stewardship of the maintainers at Red Hat. Whether deploying an in-house identity provider, or a user management system for a SaaS offering, Keycloak is an obvious choice.

With time, customer needs have evolved to include greater resiliency, expanded database selection, deploying in multiple regions, and operating across clouds. Because of operational complexity and architectural barriers, the Keycloak team decided to embark on a project to build a new underlying storage architecture. While promising, the project has taken longer than expected, and has yet to produce a production-ready result.

One of the great aspects of open source, is that it allows anyone to participate. About 18 months ago, Phase Two decided to implement support for CockroachDB for the existing storage architecture in order to meet this growing customer demand.

Remind me, what is Phase Two?

Phase Two helps SaaS builders accelerate time-to-market and enterprise adoption with powerful SSO, identity and user management features. To that end, Phase Two has created an enhanced distribution of Keycloak that bundles several essential open source extensions for modern SaaS use cases. Phase Two supports hosted and on-premise customers for a variety of use cases.

How we built support for CockroachDB

We eagerly dove into the challenge of adding CockroachDB support, but we quickly encountered a few key issues:

1. SQL

Keycloak internally uses the Hibernate ORM framework, which generates the SQL for the database type selected (called a "dialect" by them). Fortunately for us, the Cockroach Labs team had already built a custom CockroachDB Hibernate dialect that we were able to use without modification.

2. Migrations

The Liquibase library is used by Keycloak for tracking, managing, and applying database schema changes. However, the authors had not anticipated adding support for entirely new database types without making code changes. We had to add CRDB, the Hibernate dialect, and the correct JDBC driver classes to the code to enable first-class support.

We ported the migrations that were incompatible with CRDB. This was required because of a few SQL semantics that are not supported in CRDB the same way they are in PostgreSQL.

3. Transactions

Because CRDB uses serializable isolation by default, it was incompatible with Keycloak's use of distributed ("XA") or two-phase commit ("JTA") transaction managers. However, because the use of these is not necessary outside of an environment where other applications are using the same resources, it was possible to disable them. The Keycloak team was helpful in adding some environment variables to disable these, as they had also seen other database use cases that required it.

4. An Incredible Team

It also wouldn't have been possible to complete the changes without tireless support from the Cockroach Labs engineering team. They patiently helped us understand how CRDB is different, wrote code examples and tests, and were never shy about giving us access to everyone in the organization, regardless of level and how busy they were.

A HUGE thank you to the whole Cockroach team!

How does it work?

About 12 months ago, we launched our self-service, free product, built on our CRDB port and running on Cockroach Labs' managed serverless product. Over that period, we've provided over 900 free deployments, without a single production incident for both CockroachDB serverless and Phase Two enhanced Keycloak.

Furthermore, we've built out a test system that we run prior to releasing new versions in order to ensure that there are no regressions compared to the main Keycloak distributions. We run that test system and several benchmarks prior to releasing each new version of our fork.

Why is this important now?

The Keycloak team had embarked on an ambitious project over 2 years ago to completely overhaul the storage architecture. The so-called "map store" was designed, among other things, to provide a basis for high-availability by replicating data with multiple data centers. However, after that time period, there was still a lot of uncertainty and risk involved in getting to the point where the store was production ready. Thus the team decided to drop the project. See the announcement.

That leaves Phase Two's CRDB support in a unique position, as it is the only version of Keycloak that will support Cockroach's multi-region database.

Take me to it!

We get it! Here are a few links to help you jump-start your work:

1. Managed Hosting

Phase Two provides self-service deployments of Keycloak hosted on multiple clouds. Plans start with a free version for testing and small production use cases. Dedicated clusters are available for customers requiring an SLA, isolated resources, and the ability to grow into larger use cases.

The database tier for our shared and dedicated clusters uses the CockroachDB serverless service. Working with Cockroach Labs gives us the expertise and reliability of hosting thousands of customer clusters at a massive scale.

2. Community Distribution

If you're more DIY, and you're planning to run everything yourself, the base distribution image that contains our changes to Keycloak to enable CockroachDB support is available in the Phase Two Keycloak CockroachDB docker repository. It's a drop-in replacement for Keycloak that doesn't require much configuration beyond the official guides. We generally release a version within 1-2 days of the official Keycloak release.

For the impatient, we've also put together a complete docker compose example that includes a single node CockroachDB instance. You can also modify the configuration to use your own CockroachDB dedicated or serverless database.

The Future

Keycloak on CRDB

Because of the uncertainty around the direction of the Keycloak storage architecture, Phase two is committed to maintaining support for the "legacy store" and our port to CRDB for the long term.

Phase Two and Cockroach Labs

Many of our on-premise, support customers with large use cases asked us to build out a solution for massive-scale, fault-tolerant, multi-region use cases. One of the great parts of building support for Keycloak's existing storage architecture for CRDB is that we've been able to explore use cases that were previously impossible using the standard Keycloak distribution. For use cases with these requirements, plus global proximity to users and regional failover, we built global clusters, backed by CRDB multi-region database, for which we are now in Beta.

We're excited to see what you build with Keycloak and CRDB!

· One min read

In this article we'll be using Keycloak to quickly augment an application with user management and SSO. We will demonstrate the integration by securing a page for logged-in users. This quickly provides a jump-off point to more complex integrations.

info

If you just want to skip to the code, visit the Phase Two Vue example.

Setting up a Keycloak Instance

Instructions
tip

If you already have a functioning Keycloak instance, you can skip to the next section.

Rather than trying to set up a "from scratch" instance of Keycloak, we're going to short-circuit that process by leveraging a free Phase Two Starter instance. The Starter provides a free hosted instance of Phase Two's enhanced Keycloak ready for light production use cases.

  • Visit the sign-up page.

  • Enter an email, use a Github account, or use an existing Google account to register.

  • Follow the register steps. This will include a sign-in link being sent to your email. Use that for password-less login.

  • After creating an account, a realm is automatically created for you with all of the Phase Two enhancements. You need to create a Deployment in the Shared Phase Two infrastructure in order to gain access to the realm. Without a deployment created, the Create Shared Deployment modal will automatically pop up.

  • Create a Shared Deployment by providing a region (pick something close to your existing infrastructure), a name for the deployment, and selecting the default organization that was created for you upon account creation. Hit "Confirm" when ready. Standby while our robots get to work generating your deployment. This can take a few seconds.

  • After the deployment is created and active, you can access the Keycloak Admin console by clicking "Open Console" for that deployment. Open it now to see the console.

At this point, move on to the next step in the tutorial. We'll be coming back to the Admin Console when its time to start connecting our App to the Keycloak instance.

Setting up an OIDC Client

Instructions

We need to create a OpenID Connect Client in Keycloak for the app to communicate with. Keycloak's docs provide steps for how to create an OIDC client and all the various configurations that can be introduced. Follow the steps below to create a client and get the right information necessary for app configuration.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.

  2. Click Clients in the menu.

  3. Click Create client.

  4. Leave Client type set to OpenID Connect.

  5. Enter a Client ID. This ID is an alphanumeric string that is used in OIDC requests and in the Keycloak database to identify the client.

  6. Supply a Name for the client.

  7. Click Next.

  8. Under the Capability Config section, leave the defaults as selected. This can be configured further later.

    • Client authentication to On.
    • Authorization to Off.
    • Standard flow checked. Direct access grants checked. All other items unchecked.
  9. Click Next.

  10. Under Login settings we need to add a redirect URI and Web origin in order. Assuming you are using the example applicaiton:

    Valid redirect URI (allows redirect back to application)

    http://localhost:3000/*

    Web origins (allows for Token auth call)

    http://localhost:3000
    URI and Origin Details

    The choice of localhost is arbitrary. If you are using an example application running locally, this will apply. If you are using an app that you actually have deployed somewhere, then you will need to substitute the appropriate URI for that.

  11. Click Save

OIDC Config

We will need values to configure our application. To get these values follow the instructions below.

  1. Click Clients in the menu.

  2. Find the Client you just created and click on it. In the top right click the Action dropdown and select Download adapter config.

  3. Select Keycloak OIDC JSON in the format option. The details section will populate with the details we will need.

    • Note the realm, auth-server-url, and resource values.

  4. You also need to copy the Client secret in the Credential tab for the client to use. Once on the Credential tab, click the copy button to copy the key to your clipboard. Save the key somewhere for use later in this tutorial

Adding a Non-Admin User

Instructions
info

It is bad practice to use your Admin user to sign in to an Application.

Since we do not want to use our Admin user for signing into the app we will build, we need to add a another non-admin user.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.
  2. Click Users in the menu.
  3. Click Add user.
  4. Fill out the information for Email, First name, and Last name. Click Create.
  5. We will now set the password for this user manually. Click Credentials (tab) and click Set Password. Provide a password for this user. For our use case, as a tutorial, you can leave "Temporary" set to "Off".
  6. Click Save and confirm the password by clicking Save password

Setting up a Vue.js Project

info

We will use the Phase Two Vue example code here, but the logic could easily be applied to any existing application.

This example uses Vue.js. We're going to leverage oidc-client-ts to integrate OIDC authentication with the Vue app. The oidc-client-ts package is a well-maintained and used library. It provides a lot of utilities for building out a fully production app.

  1. Clone the Phase Two example repo.

  2. Open the Vue folder within /frameworks/vue and open the /nuxt/oidc-client-ts folder.

  3. Run npm install and then npm run dev.

  4. We'll review where we configure out Keycloak instance. First open /auth.ts. In this file you will want to update it with the values for the Keycloak instance we set-up earlier in the tutorial. Update the clientSecret with the value. Use and environment variable here if you wish.

    export const keycloakConfig = {
    authorityUrl: "https://euc1.auth.ac",
    applicationUrl: "http://localhost:3000",
    realm: "shared-deployment-001",
    clientId: "reg-example-1",
    clientSecret: "CLIENT_SECRET",
    };

    After the config, you can see how the OIDC instance is started.

    const settings = {
    authority: `${keycloakConfig.authorityUrl}/auth/realms/${keycloakConfig.realm}`,
    client_id: keycloakConfig.clientId,
    client_secret: keycloakConfig.clientSecret,
    redirect_uri: `${window.location.origin}/auth`,
    silent_redirect_uri: `${window.location.origin}/silent-refresh`,
    post_logout_redirect_uri: `${window.location.origin}`,
    response_type: "code",
    userStore: new WebStorageStateStore(),
    loadUserInfo: true,
    };
    this.userManager = new UserManager(settings);
  5. With the Keycloak instance defined, we attach this to the app instance for Vue. Switch to /main.ts

    import Auth from "@/auth";
    // ...
    app.config.globalProperties.$auth = Auth;

    We pull in the Auth instance then expose it through the $auth variable.

  6. There are a few main pages in play here that we define to create paths the library can leverage. The /view/auth and /view/silent-refresh create paths at the same name. These are used to do the redirection during authentication. From within these we use the Auth instance to direct the user around within the app. For instance in /views/AuthView:

    export default {
    name: "AuthAuthenticated",
    async mounted() {
    try {
    await this.$auth.signinCallback();
    this.$router.push("/");
    } catch (e) {
    console.error(e);
    }
    },
    };

    The router.push naively sends someone to the home page. This could be updated to go to any number of places, including the page one started the login flow from if you were to store that information to be retrieved.

  7. Now that we have all the things setup, we can define the user component /components/User to easily pull information about the user's state and display the appropriate UI.

    export default {
    name: "UserComponent",
    data() {
    return {
    user: null,
    signIn: () => this.$auth.signinRedirect(),
    logout: () => this.$auth.signoutRedirect(),
    };
    },
    async created() {
    const user = await this.$auth.getUser();
    if (user) {
    this.user = user;
    }
    },
    };

    With this, the user object is now easily available. A simple v-if="user" allows the app to determine what UI to show.

Learning more

Phase Two's enhanced Keycloak provides many ways to quickly control and tweak the log in and user management experience. Our blog has many use cases from customizing login pages, setting up magic links (password-less sign in), and Organization workflows.

· 7 min read

In this article we'll be using Keycloak to quickly augment an application with user management and SSO. We will demonstrate the integration by securing a page for logged-in users. This quickly provides a jump-off point to more complex integrations.

info

If you just want to skip to the code, visit the Phase Two Nuxt example.

Setting up a Keycloak Instance

Instructions
tip

If you already have a functioning Keycloak instance, you can skip to the next section.

Rather than trying to set up a "from scratch" instance of Keycloak, we're going to short-circuit that process by leveraging a free Phase Two Starter instance. The Starter provides a free hosted instance of Phase Two's enhanced Keycloak ready for light production use cases.

  • Visit the sign-up page.

  • Enter an email, use a Github account, or use an existing Google account to register.

  • Follow the register steps. This will include a sign-in link being sent to your email. Use that for password-less login.

  • After creating an account, a realm is automatically created for you with all of the Phase Two enhancements. You need to create a Deployment in the Shared Phase Two infrastructure in order to gain access to the realm. Without a deployment created, the Create Shared Deployment modal will automatically pop up.

  • Create a Shared Deployment by providing a region (pick something close to your existing infrastructure), a name for the deployment, and selecting the default organization that was created for you upon account creation. Hit "Confirm" when ready. Standby while our robots get to work generating your deployment. This can take a few seconds.

  • After the deployment is created and active, you can access the Keycloak Admin console by clicking "Open Console" for that deployment. Open it now to see the console.

At this point, move on to the next step in the tutorial. We'll be coming back to the Admin Console when its time to start connecting our App to the Keycloak instance.

Setting up an OIDC Client

Instructions

We need to create a OpenID Connect Client in Keycloak for the app to communicate with. Keycloak's docs provide steps for how to create an OIDC client and all the various configurations that can be introduced. Follow the steps below to create a client and get the right information necessary for app configuration.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.

  2. Click Clients in the menu.

  3. Click Create client.

  4. Leave Client type set to OpenID Connect.

  5. Enter a Client ID. This ID is an alphanumeric string that is used in OIDC requests and in the Keycloak database to identify the client.

  6. Supply a Name for the client.

  7. Click Next.

  8. Under the Capability Config section, leave the defaults as selected. This can be configured further later.

    • Client authentication to On.
    • Authorization to Off.
    • Standard flow checked. Direct access grants checked. All other items unchecked.
  9. Click Next.

  10. Under Login settings we need to add a redirect URI and Web origin in order. Assuming you are using the example applicaiton:

    Valid redirect URI (allows redirect back to application)

    http://localhost:3000/*

    Web origins (allows for Token auth call)

    http://localhost:3000
    URI and Origin Details

    The choice of localhost is arbitrary. If you are using an example application running locally, this will apply. If you are using an app that you actually have deployed somewhere, then you will need to substitute the appropriate URI for that.

  11. Click Save

OIDC Config

We will need values to configure our application. To get these values follow the instructions below.

  1. Click Clients in the menu.

  2. Find the Client you just created and click on it. In the top right click the Action dropdown and select Download adapter config.

  3. Select Keycloak OIDC JSON in the format option. The details section will populate with the details we will need.

    • Note the realm, auth-server-url, and resource values.

  4. You also need to copy the Client secret in the Credential tab for the client to use. Once on the Credential tab, click the copy button to copy the key to your clipboard. Save the key somewhere for use later in this tutorial

Adding a Non-Admin User

Instructions
info

It is bad practice to use your Admin user to sign in to an Application.

Since we do not want to use our Admin user for signing into the app we will build, we need to add a another non-admin user.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.
  2. Click Users in the menu.
  3. Click Add user.
  4. Fill out the information for Email, First name, and Last name. Click Create.
  5. We will now set the password for this user manually. Click Credentials (tab) and click Set Password. Provide a password for this user. For our use case, as a tutorial, you can leave "Temporary" set to "Off".
  6. Click Save and confirm the password by clicking Save password

Setting up a Nuxt Project

info

We will use the Phase Two Nuxt example code here, but the logic could easily be applied to any existing application.

This example uses Nuxt3. There are a couple methods by which you can integrate Keycloak to your Nuxt application. We're going to explore two methods here, one uses keycloak-js and the other leverages oidc-client-ts. The keycloak-js library provides a simple, client-only method, but lacks some of the sophistication provided by the oidc-client library that is heavily supported and more widely used.

Using keycloak-js

info

For this example, we need to disable "Client Authentication" in the OIDC client that was setup earlier. This is available under Client > Settings > Capability config > Client authentication to OFF.

  1. Clone the Phase Two example repo.

  2. Open the Nuxt folder within /frameworks/nuxt and open the keycloak-js folder within /frameworks/nuxt/keycloak-js.

  3. Run npm install and then npm run dev. keycloak-js is a Javascript library that provides a fast way to secure an application.

  4. The project makes use of the following Nuxt items: components, composables, layouts, and plugins. We'll review each in kind.

  5. The main component that shows the User's authenticated state is in /components/User. In this component we call the useKeycloak composable, which let's us key into the keycloak-js functions that we've wrapped to make easily availble.

    const { keycloak, authState } = useKeycloak();

    function login() {
    keycloak.login();
    }

    function logout() {
    keycloak.logout();
    }

    Lower in the file the component leverages v-if checks to determine if the authState is authenticated or not. Depending on the state, a Log in or Log out button is available.

  6. Let's take a look at the setup for the composable next. Our composable is in /composables/keycloak-c. A composable is a function defined that can be called anywhere in the Nuxt application. It's a good way to abstract logic to be reused. In our case we use it to wrap a keycloak-js plugin (more on that in the next step) and help provided a state value for the authenticated state.

    export const useKeycloak = () => {
    const nuxtApp = useNuxtApp();
    const keycloak = nuxtApp.$keycloak as Keycloak;
    const authState = useState("authState", () => "unAuthenticated");

    keycloak.onAuthSuccess = () => (authState.value = "authenticated");
    keycloak.onAuthError = () => (authState.value = "error");

    return {
    keycloak,
    authState,
    };
    };
  7. In the plugin, /plugins/keycloak.client.ts we instantiate the keycloak-js library. We can then attach that instance to the NuxtApp instance. Substitute the correct values for your Keycloak instance that we created earlier in the tutorial.

    export default defineNuxtPlugin((nuxtApp) => {
    const initOptions: KeycloakConfig = {
    url: "https://euc1.auth.ac/auth/",
    realm: "shared-deployment-001",
    clientId: "reg-example-1",
    };

    const keycloak = new Keycloak(initOptions);

    nuxtApp.$keycloak = keycloak;

    keycloak.init({
    onLoad: "check-sso",
    });
    });
  8. The logic for checking the authenticated state can be used to expand in ways to secure your site in a number of ways.

Using oidc-client

The oidc-client-ts package is a well-maintained and used library. It provides a lot of utilities for building out a fully production app.

  1. Clone the Phase Two example repo.

  2. Open the Nuxt folder within /frameworks/nuxt and open the /nuxt/oidc-client-ts folder.

  3. Run npm install and then npm run dev.

  4. The structure of the project is similar to the keycloak-js version but with a the use of services, stores, and middleware.

  5. We'll review where we configure out Keycloak instance. First open /services/keycloak-config.ts. In this file you will want to update it with the values for the Keycloak instance we set-up earlier in the tutorial. Make sure you are using the one with Client Authentication enabled. Update the clientSecret with the value. Use and environment variable here if you wish.

    export const keycloakConfig = {
    authorityUrl: "https://euc1.auth.ac",
    applicationUrl: "http://localhost:3000",
    realm: "shared-deployment-001",
    clientId: "reg-example-1",
    clientSecret: "CLIENT_SECRET",
    };
  6. Switch over to the /services/auth-service now to see how the Oidc instance is started. The class pulls in values from the keycloakConfig to use in the constructor. The other functions are wrappers around methods provided by the oidc-client library. This allows us to key into things like signInRedirect and signoutRedirect.

    How the settings are integrated:

    const settings = {
    authority: `${keycloakConfig.authorityUrl}/auth/realms/${keycloakConfig.realm}`,
    client_id: keycloakConfig.clientId,
    client_secret: keycloakConfig.clientSecret,
    redirect_uri: `${window.location.origin}/auth`,
    silent_redirect_uri: `${window.location.origin}/silent-refresh`,
    post_logout_redirect_uri: `${window.location.origin}`,
    response_type: "code",
    userStore: new WebStorageStateStore(),
    loadUserInfo: true,
    };
    this.userManager = new UserManager(settings);

    Example function wrapper:

    public signInRedirect() {
    return this.userManager.signinRedirect();
    }
  7. With the AuthService defined, we can now expose that through a composable. Switch to the /composables/useServices file. The file is simple but provides a way for any component to hook into the service instance.

    import AuthService from "@/services/auth-service";
    import ApplicationService from "@/services/application-service";
    import { useAuth } from "@/stores/auth";

    export const useServices = () => {
    const authStore = useAuth();

    return {
    $auth: new AuthService(),
    $application: new ApplicationService(authStore.access_token),
    };
    };

    We pull in the AuthService then expose it through the $auth variable. The $application variable exposes the ApplicationService which is provided as an example of how you could secure API calls.

  8. We leverage the pinia library to make store User information to make it easily accessible. Open /stores/auth/index. From within this file, we can wrap the User object exposed by the oidc-client package. This can then be leveraged in the middleware function we want to define or to pull information quickly about the user.

  9. There are a few main pages in play here that we define to create paths the library can leverage. The /pages/auth, /pages/logout, /pages/silent-refresh create paths at the same name. These are used to do the redirection during authentication or log out. From within these we use the AuthService to direct the user around within the app. For instance in /auth:

    const authenticateOidc = async () => {
    try {
    await services.$auth.signInCallback();
    router.push("/");
    } catch (error) {
    console.error(error);
    }
    };

    await authenticateOidc();

    The router.push naively sends someone to the home page. This could be updated to go to any number of places, including the page one started the login flow from if you were to store that information to be retrieved.

  10. We have also created a middleware file in /middleware/auth.global to be used in a couple of ways. It checks if the user is authenticated and based on that knowledge, stores the user information in the store (if not there) or could be used to send someone to login. For our example, we created buttons to initiate that but there is a comment which shows how you could force a set of paths to require login.

    const authFlowRoutes = ["/auth", "/silent-refresh", "/logout"];

    export default defineNuxtRouteMiddleware(async (to, from) => {
    const authStore = useAuth();
    const services = useServices();
    const user = (await services.$auth.getUser()) as User;

    if (!user && !authFlowRoutes.includes(to.path)) {
    // use this to automatically force a sign in and redirect
    // services.$auth.signInRedirect();
    } else {
    authStore.setUpUserCredentials(user);
    }
    });
  11. Now that we have all the things setup, we can define the user component /components/User to easily pull information about the user's state and display the appropriate UI.

    const authStore = useAuth();
    const user = authStore.user;

    const signIn = () => services.$auth.signInRedirect();
    const signOut = () => services.$auth.logout();

    With this, the user object is now easily available. A simple v-if="user" allows the app to determine what UI to show.

  12. A bit more complicated of a setup, but more elegant in the handling of the logged in flow. The oidc-client allows for much better fine-tuning of the experience.

Learning more

Phase Two's enhanced Keycloak provides many ways to quickly control and tweak the log in and user management experience. Our blog has many use cases from customizing login pages, setting up magic links (password-less sign in), and Organization workflows.

· 6 min read

Django is a high-level, open-source web framework for building web applications using the Python programming language. It follows the Model-View-Controller (MVC) architectural pattern.

In this article we'll be using Keycloak to secure a Django Web application.

info

If you just want to skip to the code, visit the Phase Two Django example. We are also building Keycloak examples for other frameworks.

Setting up a Django Project

The following could be applied to an existing Django application, but we have chosen to use the excellent tutorial application built by Mozilla as our example. If you aren't yet familiar with Django, we encourage you to follow the tutorial there.

The completed code for that tutorial is available in their GitHub repository. We'll clone it to get started.

Quick Start

To get this project up and running locally on your computer:

  1. Set up the Python development environment. We recommend using a Python virtual environment.
  2. Assuming you have Python setup, run the following commands (if you're on Windows you may use py or py -3 instead of python to start Python):
    pip install -r requirements.txt
    python manage.py makemigrations
    python manage.py migrate
    python manage.py collectstatic
    python manage.py test # Run the standard tests. These should all pass.
    python manage.py createsuperuser # Create a superuser
    python manage.py runserver
  3. Open a browser to http://127.0.0.1:8000/admin/ to open the admin site
  4. Create a few test objects of each type.
  5. Open tab to http://127.0.0.1:8000 to see the main site, with your new objects.

Setting up a Keycloak Instance

Before customizing the Django app, we need to set up and configure our Keycloak instance.

Instructions
tip

If you already have a functioning Keycloak instance, you can skip to the next section.

Rather than trying to set up a "from scratch" instance of Keycloak, we're going to short-circuit that process by leveraging a free Phase Two Starter instance. The Starter provides a free hosted instance of Phase Two's enhanced Keycloak ready for light production use cases.

  • Visit the sign-up page.

  • Enter an email, use a Github account, or use an existing Google account to register.

  • Follow the register steps. This will include a sign-in link being sent to your email. Use that for password-less login.

  • After creating an account, a realm is automatically created for you with all of the Phase Two enhancements. You need to create a Deployment in the Shared Phase Two infrastructure in order to gain access to the realm. Without a deployment created, the Create Shared Deployment modal will automatically pop up.

  • Create a Shared Deployment by providing a region (pick something close to your existing infrastructure), a name for the deployment, and selecting the default organization that was created for you upon account creation. Hit "Confirm" when ready. Standby while our robots get to work generating your deployment. This can take a few seconds.

  • After the deployment is created and active, you can access the Keycloak Admin console by clicking "Open Console" for that deployment. Open it now to see the console.

At this point, move on to the next step in the tutorial. We'll be coming back to the Admin Console when its time to start connecting our App to the Keycloak instance.

Setting up an OIDC Client

Instructions

We need to create a OpenID Connect Client in Keycloak for the app to communicate with. Keycloak's docs provide steps for how to create an OIDC client and all the various configurations that can be introduced. Follow the steps below to create a client and get the right information necessary for app configuration.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.

  2. Click Clients in the menu.

  3. Click Create client.

  4. Leave Client type set to OpenID Connect.

  5. Enter a Client ID. This ID is an alphanumeric string that is used in OIDC requests and in the Keycloak database to identify the client.

  6. Supply a Name for the client.

  7. Click Next.

  8. Under the Capability Config section, leave the defaults as selected. This can be configured further later.

    • Client authentication to On.
    • Authorization to Off.
    • Standard flow checked. Direct access grants checked. All other items unchecked.
  9. Click Next.

  10. Under Login settings we need to add a redirect URI and Web origin in order. Assuming you are using the example applicaiton:

    Valid redirect URI (allows redirect back to application)

    http://localhost:3000/*

    Web origins (allows for Token auth call)

    http://localhost:3000
    URI and Origin Details

    The choice of localhost is arbitrary. If you are using an example application running locally, this will apply. If you are using an app that you actually have deployed somewhere, then you will need to substitute the appropriate URI for that.

  11. Click Save

OIDC Config

We will need values to configure our application. To get these values follow the instructions below.

  1. Click Clients in the menu.

  2. Find the Client you just created and click on it. In the top right click the Action dropdown and select Download adapter config.

  3. Select Keycloak OIDC JSON in the format option. The details section will populate with the details we will need.

    • Note the realm, auth-server-url, and resource values.

  4. You also need to copy the Client secret in the Credential tab for the client to use. Once on the Credential tab, click the copy button to copy the key to your clipboard. Save the key somewhere for use later in this tutorial

Adding a Non-Admin User

Instructions
info

It is bad practice to use your Admin user to sign in to an Application.

Since we do not want to use our Admin user for signing into the app we will build, we need to add a another non-admin user.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.
  2. Click Users in the menu.
  3. Click Add user.
  4. Fill out the information for Email, First name, and Last name. Click Create.
  5. We will now set the password for this user manually. Click Credentials (tab) and click Set Password. Provide a password for this user. For our use case, as a tutorial, you can leave "Temporary" set to "Off".
  6. Click Save and confirm the password by clicking Save password

Install and configure the Django OIDC library

Now that we've installed and configured Keycloak, we need to setup Django to replace the native authentication method provided by the framework. The first task is to install a library that is compatible with Keycloak's OIDC implementation.

The mozilla-django-oidc library provides an easy way to integrate Keycloak (or any OpenID Connect-compliant identity provider) with your Django app. It abstracts many of the complexities of integrating authentication and authorization. Here's how you can set it up:

  1. Install the Package: Install the mozilla-django-oidc package using pip:

    pip install mozilla-django-oidc
  2. Configure Django Settings: Update your Django app's settings.py to include the necessary configurations for mozilla-django-oidc:

    INSTALLED_APPS = [
    # ...
    'django.contrib.auth',
    'mozilla_django_oidc', # Load after django.contrib.auth
    # ...
    ]

    AUTHENTICATION_BACKENDS = (
    'mozilla_django_oidc.auth.OIDCAuthenticationBackend',
    # ...
    )

    OIDC_RP_CLIENT_ID = 'your-client-id'
    OIDC_RP_CLIENT_SECRET = 'your-client-secret'
    OIDC_OP_AUTHORIZATION_ENDPOINT = 'https://keycloak-url/auth/realms/your-realm/protocol/openid-connect/auth'
    OIDC_OP_TOKEN_ENDPOINT = 'https://keycloak-url/auth/realms/your-realm/protocol/openid-connect/token'
    OIDC_OP_USER_ENDPOINT = 'https://keycloak-url/auth/realms/your-realm/protocol/openid-connect/userinfo'
    OIDC_OP_JWKS_ENDPOINT = 'https://keycloak-url/auth/realms/your-realm/protocol/openid-connect/certs'
    OIDC_RP_SIGN_ALGO = 'RS256'

    LOGIN_URL = 'oidc_authentication_init'
    LOGOUT_REDIRECT_URL = '/'
    LOGIN_REDIRECT_URL = '/'

    Replace your-client-id, your-client-secret, and the Keycloak URLs with your actual Keycloak configurations.

  3. Add URLs: Update your Django app's urls.py to include the authentication URLs provided by mozilla-django-oidc:

    urlpatterns += [
    path('oidc/', include('mozilla_django_oidc.urls')),
    ]

Using it in your app

Protect your views

Use Decorators for Access Control. You can now use the @oidc_protected decorator to protect views that require authentication and potentially specific roles:

from mozilla_django_oidc.decorators import oidc_protected

@oidc_protected
def protected_view(request):
# Your view logic

Accessing user information

You can access user information after authentication using the request.oidc_user attribute. For example:

def profile_view(request):
user_info = request.oidc_user.userinfo
# Access user_info['sub'], user_info['email'], etc.
# Your view logic

By default, mozilla-django-oidc looks up a Django user matching the email field to the email address returned in the user info data from Keycloak.

If a user logs into your site and doesn’t already have an account, by default, mozilla-django-oidc will create a new Django user account. It will create the User instance filling in the username (hash of the email address) and email fields.

Use Username rather than Email

mozilla-django-oidc defaults to setting up Django users using the email address as the user name from keycloak was required. Fortunately, preferred_username is set up by default in Keycloak as a claim. The claim can used by overriding the OIDCAuthenticationBackend class in mozilla_django_oidc.auth and referring to this in AUTHENTICATION_BACKENDS as below:


# Classes to override default OIDCAuthenticationBackend (Keycloak authentication)
from mozilla_django_oidc.auth import OIDCAuthenticationBackend

class KeycloakOIDCAuthenticationBackend(OIDCAuthenticationBackend):

def create_user(self, claims):
""" Overrides Authentication Backend so that Django users are
created with the keycloak preferred_username.
If nothing found matching the email, then try the username.
"""
user = super(KeycloakOIDCAuthenticationBackend, self).create_user(claims)
user.first_name = claims.get('given_name', '')
user.last_name = claims.get('family_name', '')
user.email = claims.get('email')
user.username = claims.get('preferred_username')
user.save()
return user

def filter_users_by_claims(self, claims):
""" Return all users matching the specified email.
If nothing found matching the email, then try the username
"""
email = claims.get('email')
preferred_username = claims.get('preferred_username')

if not email:
return self.UserModel.objects.none()
users = self.UserModel.objects.filter(email__iexact=email)

if len(users) < 1:
if not preferred_username:
return self.UserModel.objects.none()
users = self.UserModel.objects.filter(username__iexact=preferred_username)
return users

def update_user(self, user, claims):
user.first_name = claims.get('given_name', '')
user.last_name = claims.get('family_name', '')
user.email = claims.get('email')
user.username = claims.get('preferred_username')
user.save()
return user

In settings.py, overide the new library you have just added in AUTHENTICATION_BACKENDS :

 # mozilla_django_oidc - Keycloak authentication
"fragalysis.auth.KeycloakOIDCAuthenticationBackend",

Logging out

You can use the @oidc_logout decorator to log the user out of both your app and Keycloak:

from mozilla_django_oidc.decorators import oidc_logout

@oidc_logout
def logout_view(request):
# Your logout view logic

Add support for Django Rest Framework

Django Rest Framework (DRF) is a flexible toolkit built on top of Django, specifically designed for building RESTful APIs.

If you want DRF to authenticate users based on an OAuth access token provided in the Authorization header, you can use the DRF-specific authentication class which ships with the package.

Add this to your settings:

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'mozilla_django_oidc.contrib.drf.OIDCAuthentication',
'rest_framework.authentication.SessionAuthentication',
# other authentication classes, if needed
],
}

Note that this only takes care of authenticating against an access token, and provides no options to create or renew tokens.

If you’ve created a custom Django OIDCAuthenticationBackend and added that to your AUTHENTICATION_BACKENDS, the DRF class should be smart enough to figure that out. Alternatively, you can manually set the OIDC backend to use:

OIDC_DRF_AUTH_BACKEND = 'mozilla_django_oidc.auth.OIDCAuthenticationBackend'

Learning more

Phase Two's enhanced Keycloak provides many ways to quickly control and tweak the log in and user management experience. Our blog has many use cases from customizing login pages, setting up magic links (password-less sign in), and Organization workflows.

· 4 min read

In this article we'll be using Keycloak to quickly augment an application with user management and SSO. We will demonstrate the integration by securing a page for logged-in users. This quickly provides a jump-off point to more complex integrations.

info

If you just want to skip to the code, visit the Phase Two Next.js example. We also have a plain React example.

Setting up a Keycloak Instance

Instructions
tip

If you already have a functioning Keycloak instance, you can skip to the next section.

Rather than trying to set up a "from scratch" instance of Keycloak, we're going to short-circuit that process by leveraging a free Phase Two Starter instance. The Starter provides a free hosted instance of Phase Two's enhanced Keycloak ready for light production use cases.

  • Visit the sign-up page.

  • Enter an email, use a Github account, or use an existing Google account to register.

  • Follow the register steps. This will include a sign-in link being sent to your email. Use that for password-less login.

  • After creating an account, a realm is automatically created for you with all of the Phase Two enhancements. You need to create a Deployment in the Shared Phase Two infrastructure in order to gain access to the realm. Without a deployment created, the Create Shared Deployment modal will automatically pop up.

  • Create a Shared Deployment by providing a region (pick something close to your existing infrastructure), a name for the deployment, and selecting the default organization that was created for you upon account creation. Hit "Confirm" when ready. Standby while our robots get to work generating your deployment. This can take a few seconds.

  • After the deployment is created and active, you can access the Keycloak Admin console by clicking "Open Console" for that deployment. Open it now to see the console.

At this point, move on to the next step in the tutorial. We'll be coming back to the Admin Console when its time to start connecting our App to the Keycloak instance.

Setting up an OIDC Client

Instructions

We need to create a OpenID Connect Client in Keycloak for the app to communicate with. Keycloak's docs provide steps for how to create an OIDC client and all the various configurations that can be introduced. Follow the steps below to create a client and get the right information necessary for app configuration.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.

  2. Click Clients in the menu.

  3. Click Create client.

  4. Leave Client type set to OpenID Connect.

  5. Enter a Client ID. This ID is an alphanumeric string that is used in OIDC requests and in the Keycloak database to identify the client.

  6. Supply a Name for the client.

  7. Click Next.

  8. Under the Capability Config section, leave the defaults as selected. This can be configured further later.

    • Client authentication to On.
    • Authorization to Off.
    • Standard flow checked. Direct access grants checked. All other items unchecked.
  9. Click Next.

  10. Under Login settings we need to add a redirect URI and Web origin in order. Assuming you are using the example applicaiton:

    Valid redirect URI (allows redirect back to application)

    http://localhost:3000/*

    Web origins (allows for Token auth call)

    http://localhost:3000
    URI and Origin Details

    The choice of localhost is arbitrary. If you are using an example application running locally, this will apply. If you are using an app that you actually have deployed somewhere, then you will need to substitute the appropriate URI for that.

  11. Click Save

OIDC Config

We will need values to configure our application. To get these values follow the instructions below.

  1. Click Clients in the menu.

  2. Find the Client you just created and click on it. In the top right click the Action dropdown and select Download adapter config.

  3. Select Keycloak OIDC JSON in the format option. The details section will populate with the details we will need.

    • Note the realm, auth-server-url, and resource values.

  4. You also need to copy the Client secret in the Credential tab for the client to use. Once on the Credential tab, click the copy button to copy the key to your clipboard. Save the key somewhere for use later in this tutorial

Adding a Non-Admin User

Instructions
info

It is bad practice to use your Admin user to sign in to an Application.

Since we do not want to use our Admin user for signing into the app we will build, we need to add a another non-admin user.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.
  2. Click Users in the menu.
  3. Click Add user.
  4. Fill out the information for Email, First name, and Last name. Click Create.
  5. We will now set the password for this user manually. Click Credentials (tab) and click Set Password. Provide a password for this user. For our use case, as a tutorial, you can leave "Temporary" set to "Off".
  6. Click Save and confirm the password by clicking Save password

Setting up a Next.js Project

info

We will use the Phase Two Next.js example code here, but the logic could easily be applied to any existing application.

This example uses Next.js 13 and splits server and client components accordingly.

  1. Clone the Phase Two example repo.

  2. Open the Next.js folder within /frameworks/nextjs.

  3. Run npm install and then npm run dev. This example leverages NextAuth.js to provide hook and HOC support.

  4. NextAuth.js configures an API route that is uses for the Authentication of the Client. It generates the routes automatically for you. These are added to Next.js in the api/auth/[...nextauth]/route.ts file.

  5. Open the src/lib/auth.ts file. This is a server only file. We will be updating a few values from the prior section where we set up our OIDC client. Taking the values from the OIDC Client Config section, set those values in the code. While it is recommended to use Environment variables for the secret, for the purpose of this tutorial, paste in the Client secret from the OIDC client creation section for the value of clientSecret

    const authServerUrl = "https://euc1.auth.ac/auth/";
    const realm = "shared-deployment-001";
    const clientId = "reg-example-1";
    const clientSecret = "CLIENT_SECRET"; // Paste "Client secret" here. Use Environment variables in prod

    Those are used to popluate the AuthOptions config for the KeycloakProvider:

    export const AuthOptions: NextAuthOptions = {
    providers: [
    KeycloakProvider({
    clientId,
    clientSecret,
    issuer: `${authServerUrl}realms/${realm}`,
    }),
    ],
    };

    The config is then provided to the AuthProvider in the /src/app/layout.tsx file. Next.js uses this file to generate an HTML view for this page.

    import { NextAuthProvider as AuthProvider } from "./providers";
    ...
    <AuthProvider {...oidcConfig}>
    <App />
    </AuthProvider>

    At this point our entire application will be able to access all information and methods needed to perform authentication. View the providers.tsx file for additional information about how the SessionProvider is used. The SessionProvider enables use of Hooks to derive the authenticated state. View user.component.tsx for exactly how the code is authenticating your user. The sections rendering the "Log in" and "Log out" buttons are conditional areas based on the authenticated context. The buttons invoke functions provided by NextAuth.

    The logic using the hook to conditionally determine the Authenticated state, can be used to secure routes, components, and more.

  6. Open localhost:3000. You will see the Phase Two example landing page. You current state should be "Not authenticated". Click Log In. This will redirect you to your login page.

    info

    Use the non-admin user created in the previous section to sign in.

  7. Enter the credentials of the non-admin user you created. Click Submit. You will then be redirected to the application. The Phase Two example landing page now loads your "Authenticated" state, displaying your user's email and their Token.

  8. After your first log in, click Log out. Then click Log in again. Notice how this time you will not be redirected to sign in as your state is already in the browser. Neat! If you clear the browser state for that tab, then you will have to be redirected away to sign-in again.

Learning more

Phase Two's enhanced Keycloak provides many ways to quickly control and tweak the log in and user management experience. Our blog has many use cases from customizing login pages, setting up magic links (password-less sign in), and Organization workflows.

· 3 min read

In this article we'll be using Keycloak to quickly augment an application with user management and SSO. We will demonstrate the integration by securing a page for logged-in users. This quickly provides a jump-off point to more complex integrations.

info

If you just want to skip to the code, visit the Phase Two ReactJS example.

Setting up a Keycloak Instance

Instructions
tip

If you already have a functioning Keycloak instance, you can skip to the next section.

Rather than trying to set up a "from scratch" instance of Keycloak, we're going to short-circuit that process by leveraging a free Phase Two Starter instance. The Starter provides a free hosted instance of Phase Two's enhanced Keycloak ready for light production use cases.

  • Visit the sign-up page.

  • Enter an email, use a Github account, or use an existing Google account to register.

  • Follow the register steps. This will include a sign-in link being sent to your email. Use that for password-less login.

  • After creating an account, a realm is automatically created for you with all of the Phase Two enhancements. You need to create a Deployment in the Shared Phase Two infrastructure in order to gain access to the realm. Without a deployment created, the Create Shared Deployment modal will automatically pop up.

  • Create a Shared Deployment by providing a region (pick something close to your existing infrastructure), a name for the deployment, and selecting the default organization that was created for you upon account creation. Hit "Confirm" when ready. Standby while our robots get to work generating your deployment. This can take a few seconds.

  • After the deployment is created and active, you can access the Keycloak Admin console by clicking "Open Console" for that deployment. Open it now to see the console.

At this point, move on to the next step in the tutorial. We'll be coming back to the Admin Console when its time to start connecting our App to the Keycloak instance.

Setting up an OIDC Client

Instructions

We need to create a OpenID Connect Client in Keycloak for the app to communicate with. Keycloak's docs provide steps for how to create an OIDC client and all the various configurations that can be introduced. Follow the steps below to create a client and get the right information necessary for app configuration.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.

  2. Click Clients in the menu.

  3. Click Create client.

  4. Leave Client type set to OpenID Connect.

  5. Enter a Client ID. This ID is an alphanumeric string that is used in OIDC requests and in the Keycloak database to identify the client.

  6. Supply a Name for the client.

  7. Click Next.

  8. Under the Capability Config section, leave the defaults as selected. This can be configured further later.

    • Client authentication to Off.
    • Authorization to Off.
    • Standard flow checked. Direct access grants checked. All other items unchecked.
  9. Click Next.

  10. Under Login settings we need to add a redirect URI and Web origin in order. Assuming you are using the example applicaiton:

    Valid redirect URI (allows redirect back to application)

    http://localhost:3000/*

    Web origins (allows for Token auth call)

    http://localhost:3000
    URI and Origin Details

    The choice of localhost is arbitrary. If you are using an example application running locally, this will apply. If you are using an app that you actually have deployed somewhere, then you will need to substitute the appropriate URI for that.

  11. Click Save

OIDC Config

We will need values to configure our application. To get these values follow the instructions below.

  1. Click Clients in the menu.

  2. Find the Client you just created and click on it. In the top right click the Action dropdown and select Download adapter config.

  3. Select Keycloak OIDC JSON in the format option. The details section will populate with the details we will need.

    • Note the realm, auth-server-url, and resource values.

Adding a Non-Admin User

Instructions
info

It is bad practice to use your Admin user to sign in to an Application.

Since we do not want to use our Admin user for signing into the app we will build, we need to add a another non-admin user.

  1. Open the Admin UI by clicking Open Console in the Phase Two Dashboard.
  2. Click Users in the menu.
  3. Click Add user.
  4. Fill out the information for Email, First name, and Last name. Click Create.
  5. We will now set the password for this user manually. Click Credentials (tab) and click Set Password. Provide a password for this user. For our use case, as a tutorial, you can leave "Temporary" set to "Off".
  6. Click Save and confirm the password by clicking Save password

Setting up a ReactJS Project

info

We will use the Phase Two ReactJS example code here, but the logic could easily be applied to any existing application.

  1. Clone the Phase Two example repo.

  2. Open the ReactJS folder within /frameworks/reactjs.

  3. Run npm install and then npm start. This example leverages react-oidc-context (which uses oidc-client-ts) to provide hook and HOC support.

  4. Open the index.tsx file. We will be updating a few values from the prior section where we set up our OIDC client. Taking the values from the OIDC Client Config section, set those values in the code.

    const authServerUrl = "https://euc1.auth.ac/auth/";
    const realm = "shared-deployment-001";
    const client = "reg-example-1";

    Those are used to popluate the OIDC config

    const oidcConfig = {
    authority: `${authServerUrl}realms/${realm}`,
    client_id: client,
    redirect_uri: "http://localhost:3000/authenticated",
    onSigninCallback: (args: any) =>
    window.history.replaceState(
    {},
    document.title,
    window.location.pathname
    ),
    };

    The config is then provided to the AuthProvider.

    <AuthProvider {...oidcConfig}>
    <App />
    </AuthProvider>

    At this point our entire applicationw will be able to access all information and methods needed to perform authentication. View Auth.tsx for exactly how the code is authenticating your user. The sections rendering the "Log in" and "Log out" buttons are conditional areas based on the authenticated context.

    The logic using the hook to conditionally determine the Authenticated state, can be used to secure routes, components, and more.

  5. Open localhost:3000. You will see the Phase Two example landing page. You current state should be "Not authenticated". Click Log In. This will redirect you to your login page.

    info

    Use the non-admin user created in the previous section to sign in.

  6. Enter the credentials of the non-admin user you created. Click Submit. You will then be redirected to the application. The Phase Two example landing page now loads your "Authenticated" state, displaying your user's email and their Token.

  7. After your first log in, click Log out. Then click Log in again. Notice how this time you will not be redirected to sign in as your state is already in the browser. Neat! If you clear the browser state for that tab, then you will have to be redirected away to sign-in again.

Learning more

Phase Two's enhanced Keycloak provides many ways to quickly control and tweak the log in and user management experience. Our blog has many use cases from customizing login pages, setting up magic links (password-less sign in), and Organization workflows.

· 4 min read

We're excited today to announce the launch of our dedicated clusters offering. Our Phase Two enhanced Keycloak distribution is now available as a hosted, dedicated cluster in the region of your choice.

About 9 months ago, we launched our self-service, shared deployments, offering customers the ability to create Phase Two enhanced Keycloak realms on our shared clusters. Over that period, we've provided over 700 free realms for testing and small production use cases. Many of you have reached out to us asking about an SLA, isolated resources, and ability to grow into larger use cases. Based on your requests and feedback, we built out our dedicated cluster offering.

What is Phase Two again?

Phase Two helps SaaS builders accelerate time-to-market and enterprise adoption with powerful SSO, identity and user management features. To that end, Phase Two has created an enhanced distribution of Keycloak that bundles several essential open source extensions for modern SaaS use cases. We support hosted and on-prem customers for a variety of use cases.

Why dedicated?

Dedicated clusters allow us to provide compute, network and storage isolation for customer workloads, and to easily deploy in the region where customer's users are. With dedicated clusters, we can guarantee an SLA that meets customer's needs with no resource contention from other customers.

Furthermore, it allows us to support customer-provided domain names, and access to monitoring and management capabilities not available in the shared clusters.

How did you do it?

We built out our dedicated cluster offering using the best-of-breed open source tools and managed services.

The core consists of Kubernetes clusters in each supported AWS and GCP region. New dedicated clusters are provisioned instantly using FluxCD, a continuous delivery solution that gives us the history and auditability of git. Monitoring and alerting is done using Prometheus, Grafana, and a suite of external services that give us a complete view of cluster health.

The database tier uses a managed CockroachDB service provided by Cockroach Labs. Phase Two is the only provider that is capable of hosting the current Keycloak distribution (the "legacy" store) using CockroachDB. Working with Cockroach Labs gives us the expertise and reliability from hosting thousands of customer clusters at massive scale.

Take me to it!

Starting today, you'll be able to log into the updated dashboard, and create your dedicated cluster by selecting a region and setting up your billing information.

Following successful billing setup, you will be returned to the Dashboard while your Cluster is provisioned. Once provisioned, you'll be able to create up to 20 realms per cluster, using the same easy setup as you are used to in the shared deployment offering.

Most clusters will be provisioned within 30 minutes, but some requests may take up to 24 hours. Additionally, for payment types such as ACH or SEPA, cluster provisioning will begin following payment clearing (up to 4 days in some cases).

How much does it cost?

Plans start at $499US per month when paid annually. This provides a set of compute, network and storage resources that have been tested for common use cases for up to 20 realms and 1 million users. If your use case is uncommon or you plan to scale beyond that, our system is designed to scale up with your needs. Our plans scale linearly with resource demands beyond our minimums.

We will continue to support a robust Free tier.

What's next? (psst... Global clusters)

Many of our on-prem, suppport customers with large use cases asked us to build out a solution for massive-scale, fault-tolerant, multi-region use cases. One of the great parts of building support for Keycloak's existing storage system for CockroacDB is that we've been able to explore use cases that were previously impossible using the standard Keycloak distribution, or required complex, error-prone configurations. For use cases with these requirements, plus global proximity to users and regional failover, we built global clusters, backed by CockroachDB multi-region database, for which we are now in beta.

These clusters provide a minimum of 3 global regions, with 3 instances of Phase Two enhanced Keycloak per region. Global server load balancing provides geographic region affinity and failover to connect your users with the closest, available instances.

There will be two price tiers for global clusters, depending on your use of our shared CockroachDB clusters, or your own dedicated clusters. We expect to launch general availability of global clusters later in Q3 2023.

Please contact sales@phasetwo.io to talk to us about your global cluster use case.

· 3 min read

Brand is important to modern SaaS companies, and nowhere is that more apparent than at the front door: the login experience. Unfortunately, the default design of the Keycloak login experience has a "face only a mother could love".

In order to allow customers to customize that experience, we've extended the default Keycloak theming functionality to allow you to easily customize the login pages from the admin console. This eliminates the need to package and deploy a custom theme, and allows fast iteration without restart.

Simple customization

If you're in a hurry, logo and color customization can be achieved by adding your logo's URL and three color choices. These are available in the General and Login tabs of the Styles section.

In order for these setting to take effect, your Realm Settings Themes must also be set to Attributes for the Login theme type

Full customization using CSS

Many of you will have more stringent branding requirements. For this, you can override the styles of the default Keycloak login theme. To discover the base styles that are available using this theme, we recommend

Note that using CSS overrides will cause the colors from simple customization not to work.

In order to load your CSS, paste it into the "CSS" field in the Login tab of the Styles section.

This CSS will be the last CSS loaded, overridding the styles in the default keycloak login theme.

References:

CSS Examples

To get you started with some ideas, we've created 3 example login themes that were done by overridding the CSS. These are free of license restriction, so feel free to download, use and customize the CSS at the links with the example images.

Images and other assets

You'll notice that images, icons and fonts not found in the standard Keycloak themes are used. These are referenced by URL in the CSS. For example, if you are used to loading a custom font in the <head> of your HTML, it is possible to do it in CSS using @import:

@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Lexend+Deca:wght@300;400;500;600;700&family=Lexend:wght@300;400;500;600;700&family=Work+Sans:wght@300;400;500;600;700&display=swap");

And background and other images can be referenced by their full URL using url(...):

.login-pf body {
background-image: url("https://raw.githubusercontent.com/p2-inc/keycloak-themes/main/examples/saas/assets/SaaS%20BG.webp");
}

Success!

As always, our success is based on the success of our customers. We hope this extension and guide has helped you update the default Keycloak login branding to match that of your needs. If you have suggestions for further improvement of this feature, please reach out on GitHub!