技能 编程开发 Webiny Okta身份认证配置

Webiny Okta身份认证配置

v20260424
webiny-configure-okta
本技能用于将Okta配置为Webiny项目的外部身份提供方(IDP)。它指导开发者如何使用OIDC标准,替换默认的认证机制。核心步骤包括:创建API配置类来映射Okta的JWT声明到Webiny身份数据,并通过React扩展组件完成环境配置和流程绑定,从而实现基于Okta的单点登录(SSO)认证。
获取技能
213 次下载
概览

Configure Okta Authentication

TL;DR

Webiny supports Okta as an external identity provider (IDP) to replace the default Cognito authentication. First, install the @webiny/okta package (using the same version as the webiny dependency in package.json). Then create two files: an API config class that maps Okta JWT claims to Webiny identity data (OktaIdpConfig), and a React extension component (<Okta />) that wires issuer URL, client ID, and the API config path. Register the extension in webiny.config.tsx, set two environment variables (OKTA_ISSUER, OKTA_CLIENT_ID), and deploy.

Pattern / Core Concept

Okta integration has two parts:

  1. API Config — A class implementing OktaIdpConfig.Interface that maps JWT token claims to Webiny's identity structure. Registered via OktaIdpConfig.createImplementation() (the universal DI pattern).
  2. Extension Component — A React component that renders <Okta /> from @webiny/okta, passing the issuer URL, client ID, and path to the API config file. The <Okta /> component handles environment variable injection, API extension registration, and Admin login screen setup automatically.

How <Okta /> Works Internally

The <Okta /> component (from @webiny/okta) is a defineExtension that:

  • Sets Lambda env vars: OKTA_ISSUER, OKTA_CLIENT_ID
  • Sets Admin app env vars: REACT_APP_IDP_TYPE=okta, REACT_APP_OKTA_ISSUER, REACT_APP_OKTA_CLIENT_ID
  • Registers the internal OktaIdpFeature API extension (OIDC token verification)
  • Registers your custom API config extension (identity mapping)
  • Registers the Admin Okta login screen extension

Reference Tables

OktaIdpConfig.Interface

Method Signature Required Description
getIdentity (token: JwtPayload) => OktaIdentity | Promise<OktaIdentity> Yes Maps JWT claims to Webiny identity data
verifyTokenClaims (token: JwtPayload) => void | Promise<void> No Custom claim verification (throw to reject the token)

OktaIdentity (Return Type of getIdentity)

Field Type Description
id string Unique user ID (typically token["sub"])
displayName string User's display name
roles string[] Webiny security roles to assign
teams string[] Webiny teams (optional, filter out falsy values)
profile { firstName, lastName, email } User profile fields
context object Runtime data (not stored in DB)

<Okta /> Component Props

Prop Type Description
issuer string Okta issuer URL (e.g., https://dev-xxx.okta.com)
clientId string Okta application client ID
apiConfig string Absolute path to the API config file

Environment Variables

Variable Used By Description
OKTA_ISSUER API + Admin Okta issuer URL
OKTA_CLIENT_ID API + Admin Okta application client ID

Full Examples

Example 1: Basic Okta Configuration

Step 0: Install the @webiny/okta dependency

@webiny/okta is an optional dependency. Add it to package.json using the same version as the webiny dependency, then install:

# Check the webiny version in package.json, then add @webiny/okta with the same version
# For example, if "webiny": "^0.0.0-unstable.xxx":
yarn add @webiny/okta@^0.0.0-unstable.xxx

Important: After adding the dependency, tell the user to run yarn to install it. Do NOT run yarn automatically — let the user do it.

Step 1: Create the API config

Create extensions/okta/MyOktaConfig.ts:

import { OktaIdpConfig } from "@webiny/okta";

class MyIdpConfig implements OktaIdpConfig.Interface {
  getIdentity(token: OktaIdpConfig.JwtPayload) {
    return {
      id: String(token["sub"]),
      displayName: token["name"],
      roles: [token["webiny_group"]],
      teams: [token["team"]].filter(Boolean),
      profile: {
        firstName: token["first_name"],
        lastName: token["last_name"],
        email: token["email"]
      },
      context: {
        canAccessTenant: true,
        defaultTenant: "root"
      }
    };
  }
}

const MyOktaConfig = OktaIdpConfig.createImplementation({
  implementation: MyIdpConfig,
  dependencies: []
});

export default MyOktaConfig;

Step 2: Create the extension component

Create extensions/okta/MyOktaExtension.tsx:

import React from "react";
import { Okta } from "@webiny/okta";

export const MyOktaExtension = () => {
  return (
    <Okta
      issuer={String(process.env.OKTA_ISSUER)}
      clientId={String(process.env.OKTA_CLIENT_ID)}
      apiConfig={import.meta.dirname + "/MyOktaConfig.ts"}
    />
  );
};

Step 3: Register in webiny.config.tsx

import React from "react";
import { MyOktaExtension } from "./extensions/okta/MyOktaExtension.js";

export const Extensions = () => {
  return (
    <>
      {/* Replace <Cognito /> with Okta */}
      <MyOktaExtension />

      {/* ... other extensions ... */}
    </>
  );
};

Step 4: Set environment variables

Add to your .env file (or CI/CD environment):

OKTA_ISSUER=https://dev-xxxxx.okta.com/oauth2/default
OKTA_CLIENT_ID=your-okta-client-id

Step 5: Deploy

yarn webiny deploy

Example 2: Custom Claim Verification

If your Okta setup uses custom claims that need validation:

import { OktaIdpConfig } from "@webiny/okta";

class MyIdpConfig implements OktaIdpConfig.Interface {
  getIdentity(token: OktaIdpConfig.JwtPayload) {
    return {
      id: String(token["sub"]),
      displayName: token["name"],
      roles: [token["webiny_role"]],
      profile: {
        firstName: token["given_name"],
        lastName: token["family_name"],
        email: token["email"]
      },
      context: {
        canAccessTenant: true,
        defaultTenant: "root"
      }
    };
  }

  verifyTokenClaims(token: OktaIdpConfig.JwtPayload) {
    // Reject tokens without the required custom claim
    if (!token["webiny_role"]) {
      throw new Error("Token is missing the 'webiny_role' claim.");
    }

    // Reject tokens from unauthorized organizations
    const allowedOrgs = ["org_abc123", "org_def456"];
    if (!allowedOrgs.includes(token["org_id"] as string)) {
      throw new Error("User does not belong to an authorized organization.");
    }
  }
}

const MyOktaConfig = OktaIdpConfig.createImplementation({
  implementation: MyIdpConfig,
  dependencies: []
});

export default MyOktaConfig;

Example 3: Using DI Dependencies in Config

If your config needs access to other Webiny services (e.g., to look up tenant-specific roles):

import { OktaIdpConfig } from "@webiny/okta";
import { TenantContext } from "webiny/api/tenancy";

class MyIdpConfig implements OktaIdpConfig.Interface {
  constructor(private tenantContext: TenantContext.Interface) {}

  getIdentity(token: OktaIdpConfig.JwtPayload) {
    const tenant = this.tenantContext.getTenant();

    return {
      id: String(token["sub"]),
      displayName: token["name"],
      roles: [token["webiny_group"]],
      profile: {
        firstName: token["first_name"],
        lastName: token["last_name"],
        email: token["email"]
      },
      context: {
        canAccessTenant: true,
        defaultTenant: tenant?.id ?? "root"
      }
    };
  }
}

const MyOktaConfig = OktaIdpConfig.createImplementation({
  implementation: MyIdpConfig,
  dependencies: [TenantContext]
});

export default MyOktaConfig;

Quick Reference

Imports

// API config
import { OktaIdpConfig } from "@webiny/okta";

// Extension component
import { Okta } from "@webiny/okta";

Key Interfaces

Interface Package Purpose
OktaIdpConfig.Interface @webiny/okta API-side JWT-to-identity mapping
OktaIdpConfig.JwtPayload @webiny/okta JWT token payload type
OktaIdpConfig.IdentityData @webiny/okta Identity return type

File Structure

extensions/okta/
├── MyOktaConfig.ts        # API config (JWT claim mapping)
└── MyOktaExtension.tsx    # Extension component (Okta setup)

Registration

In webiny.config.tsx, replace <Cognito /> with <MyOktaExtension />.

Deploy

yarn webiny deploy        # Deploy all (Core + API + Admin)

Both API and Admin need to be redeployed since Okta affects both the backend (token verification, identity mapping) and the frontend (login screen).

Related Skills

  • webiny-dependency-injection — The universal DI pattern used by OktaIdpConfig.createImplementation()
  • webiny-project-structure — How webiny.config.tsx and extensions are organized
  • webiny-local-development — Deploying and testing your Okta configuration
信息
Category 编程开发
Name webiny-configure-okta
版本 v20260424
大小 10.21KB
更新时间 2026-04-28
语言