Agent Skillswebiny/webiny-js › webiny-configure-entraid

webiny-configure-entraid

GitHub

指导在 Webiny 项目中配置 Microsoft Entra ID (Azure AD) 作为联合身份提供商,通过 Cognito Federation 实现 OIDC 登录集成。

skills/user-skills/configure-entraid/SKILL.md webiny/webiny-js

Trigger Scenarios

配置 Microsoft Entra ID 设置 Azure AD SSO Webiny OIDC 集成

Install

npx skills add webiny/webiny-js --skill webiny-configure-entraid -g -y
More Options

Non-standard path

npx skills add https://github.com/webiny/webiny-js/tree/next/skills/user-skills/configure-entraid -g -y

Use without installing

npx skills use webiny/webiny-js@webiny-configure-entraid

指定 Agent (Claude Code)

npx skills add webiny/webiny-js --skill webiny-configure-entraid -a claude-code -g -y

安装 repo 全部 skill

npx skills add webiny/webiny-js --all -g -y

预览 repo 内 skill

npx skills add webiny/webiny-js --list

SKILL.md

Frontmatter
{
    "name": "webiny-configure-entraid",
    "description": "Configuring Microsoft Entra ID (formerly Azure AD) as a federated identity provider for Webiny projects using Cognito Federation. Use this skill when the developer asks about Entra ID, Azure AD, Microsoft SSO, OIDC with Microsoft, Microsoft login for Webiny, or configuring login.microsoftonline.com as an identity provider. Also relevant for tenant IDs, Entra application registration, or connecting Microsoft 365 accounts to Webiny."
}

Configure Microsoft Entra ID Authentication

TL;DR

Webiny supports Microsoft Entra ID (formerly Azure AD) as a federated identity provider through Cognito Federation. Unlike Okta or Auth0 which replace Cognito entirely, Entra ID works alongside Cognito — users authenticate via Microsoft, but Cognito remains the user pool. Configure it by adding federation to the <Cognito /> extension in webiny.config.tsx with your Entra ID application's client ID, client secret, and issuer URL.

Prerequisites

Before configuring Webiny, you need to register an application in the Microsoft Entra ID portal:

  1. Go to Microsoft Entra admin center > App registrations > New registration
  2. Set a name (e.g., "Webiny Admin")
  3. Set Supported account types (typically "Accounts in this organizational directory only")
  4. Set Redirect URI: Web — use your Cognito domain callback URL (you'll get this after the first deploy: https://{domain}.auth.{region}.amazoncognito.com/oauth2/idpresponse)
  5. After registration, note:
    • Application (client) ID — this is your client_id
    • Directory (tenant) ID — part of your issuer URL
  6. Go to Certificates & secrets > New client secret — note the Value (this is your client_secret)
  7. The Issuer URL is: https://login.microsoftonline.com/{tenant-id}/v2.0

Reference Tables

Required Entra ID Values

Value Where to find it Used as
Application (client) ID App registration > Overview client_id in providerDetails
Client secret value App registration > Certificates & secrets client_secret in providerDetails
Directory (tenant) ID App registration > Overview Part of oidc_issuer URL

Environment Variables

Variable Description
ENTRA_CLIENT_ID Entra ID Application (client) ID
ENTRA_CLIENT_SECRET Entra ID client secret value
ENTRA_ISSUER https://login.microsoftonline.com/{tenant-id}/v2.0

Attribute Mapping

When Cognito receives tokens from Entra ID, it maps the OIDC claims to Cognito user attributes. The default OIDC mapping is:

Cognito Attribute OIDC Claim Description
username sub Unique user identifier
custom:id sub Webiny internal user ID
email email User's email address
given_name given_name First name
family_name family_name Last name
preferred_username email Used as the Cognito username alias

You can override this mapping with the attributeMapping property on the identity provider config. This is useful when:

  • Your Entra ID uses non-standard claim names
  • You want to skip custom:id mapping (e.g., when the sub value exceeds the attribute's max length on existing pools)
  • You need to map additional custom attributes
{
    name: "EntraID",
    type: "oidc",
    label: "Sign in with Microsoft",
    providerDetails: { /* ... */ },
    attributeMapping: {
        username: "sub",
        email: "email",
        given_name: "given_name",
        family_name: "family_name",
        preferred_username: "email"
        // custom:id intentionally omitted
    }
}

When attributeMapping is provided, it replaces the defaults entirely — include all mappings you need.

Full Examples

Example 1: Basic Entra ID Federation

Step 1: Set environment variables

Add to your .env file:

# NOTE: these are made up example values
ENTRA_CLIENT_ID=f62ee823-2811-8314-a040-62848442c0d5
ENTRA_CLIENT_SECRET=~Gp7Q~97MAzTAUyeTLzTVzX31DRTY28chehU6c_a
ENTRA_ISSUER=https://login.microsoftonline.com/1cd0d912-0ac4-48a0-91b6-cd849ce9498f/v2.0

Step 2: Create the extension

Create extensions/entraid/Extension.tsx:

import React from "react";
import { Cognito } from "@webiny/cognito";

export const CognitoFederation = () => {
  return (
    <Cognito
      federation={{
        domain: "my-app-entraid",
        callbackUrls: ["http://localhost:3001"],
        responseType: "code",
        identityProviders: [
          {
            name: "EntraID",
            type: "oidc",
            label: "Sign in with Microsoft",
            providerDetails: {
              attributes_request_method: "POST",
              authorize_scopes: "email profile openid",
              client_id: String(process.env.ENTRA_CLIENT_ID),
              client_secret: String(process.env.ENTRA_CLIENT_SECRET),
              oidc_issuer: String(process.env.ENTRA_ISSUER)
            }
          }
        ]
      }}
    />
  );
};

Step 3: Register in webiny.config.tsx

import { CognitoFederation } from "@/extensions/entraid/Extension.js";

export const Extensions = () => {
  return (
    <>
      {/* Replace <Cognito /> with the federation extension */}
      <CognitoFederation />

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

Step 4: Deploy

# Deploy core first (creates Cognito IdP resources)
yarn webiny deploy core --env=dev

# Get the Cognito domain for Entra ID redirect URI config
yarn webiny output core --env=dev
# Look for cognitoUserPoolDomain — use it to update the redirect URI in Entra ID

# Deploy API + Admin
yarn webiny deploy api --env=dev
yarn webiny deploy admin --env=dev

Step 5: Update Entra ID redirect URI

After the first deploy, update the redirect URI in your Entra ID app registration to: https://{cognitoUserPoolDomain}/oauth2/idpresponse

Example 2: Entra ID Only (No Password Login)

<Cognito
  federation={{
    domain: "my-app-entraid",
    callbackUrls: ["http://localhost:3001", "https://admin.example.com"],
    responseType: "code",
    allowCredentialsLogin: false,
    identityProviders: [
      {
        name: "EntraID",
        type: "oidc",
        label: "Sign in with Microsoft",
        providerDetails: {
          attributes_request_method: "POST",
          authorize_scopes: "email profile openid",
          client_id: String(process.env.ENTRA_CLIENT_ID),
          client_secret: String(process.env.ENTRA_CLIENT_SECRET),
          oidc_issuer: String(process.env.ENTRA_ISSUER)
        }
      }
    ]
  }}
/>

This hides the email/password form and shows only the "Sign in with Microsoft" button with a description that the user will be redirected.

Example 3: Entra ID with Custom Role Mapping

Map Entra ID groups (via Cognito groups or token claims) to Webiny roles:

// webiny.config.tsx
<CognitoFederation />
// where CognitoFederation includes:
// apiConfig={"@/extensions/entraid/api.ts"}
// extensions/entraid/api.ts
import { CognitoIdpConfig } from "@webiny/cognito/api";

class EntraIdConfig implements CognitoIdpConfig.Interface {
  getIdentity(token: CognitoIdpConfig.JwtPayload) {
    const groups: string[] = (token["cognito:groups"] as string[]) || [];

    return {
      roles: groups.includes("WebinyAdmins") ? ["full-access"] : ["content-editor"],
      teams: groups.filter(g => g.startsWith("team-"))
    };
  }
}

export default CognitoIdpConfig.createImplementation({
  implementation: EntraIdConfig,
  dependencies: []
});

Example 4: Production Setup with Multiple Callback URLs

<Cognito
  federation={{
    domain: "mycompany-webiny",
    callbackUrls: ["http://localhost:3001", "https://admin.mycompany.com"],
    logoutUrls: ["http://localhost:3001", "https://admin.mycompany.com"],
    responseType: "code",
    allowCredentialsLogin: false,
    identityProviders: [
      {
        name: "EntraID",
        type: "oidc",
        label: "Sign in with Microsoft",
        providerDetails: {
          attributes_request_method: "POST",
          authorize_scopes: "email profile openid",
          client_id: String(process.env.ENTRA_CLIENT_ID),
          client_secret: String(process.env.ENTRA_CLIENT_SECRET),
          oidc_issuer: String(process.env.ENTRA_ISSUER)
        }
      }
    ]
  }}
/>

Remember to add all callback URLs to your Entra ID app registration's redirect URIs.

Example 5: Custom Attribute Mapping

Override the default claim mapping — useful for existing Cognito pools where custom:id has a max length of 36 characters (Entra ID sub values can be longer):

<Cognito
  federation={{
    domain: "mycompany-webiny",
    callbackUrls: ["http://localhost:3001"],
    identityProviders: [
      {
        name: "EntraID",
        type: "oidc",
        label: "Sign in with Microsoft",
        providerDetails: {
          attributes_request_method: "POST",
          authorize_scopes: "email profile openid",
          client_id: String(process.env.ENTRA_CLIENT_ID),
          client_secret: String(process.env.ENTRA_CLIENT_SECRET),
          oidc_issuer: String(process.env.ENTRA_ISSUER)
        },
        attributeMapping: {
          username: "sub",
          email: "email",
          given_name: "given_name",
          family_name: "family_name",
          preferred_username: "email"
        }
      }
    ]
  }}
/>

Example 6: Entra ID with MFA

Add TOTP-based MFA on top of Entra ID federation:

<Cognito
  mfa={true}
  federation={{
    domain: "mycompany-webiny",
    callbackUrls: ["http://localhost:3001"],
    allowCredentialsLogin: false,
    identityProviders: [
      {
        name: "EntraID",
        type: "oidc",
        label: "Sign in with Microsoft",
        providerDetails: {
          attributes_request_method: "POST",
          authorize_scopes: "email profile openid",
          client_id: String(process.env.ENTRA_CLIENT_ID),
          client_secret: String(process.env.ENTRA_CLIENT_SECRET),
          oidc_issuer: String(process.env.ENTRA_ISSUER)
        },
        attributeMapping: {
          "custom:id": "sub",
          username: "sub",
          email: "email",
          given_name: "given_name",
          family_name: "family_name",
          preferred_username: "email"
        }
      }
    ]
  }}
/>

MFA applies to password-based logins. Federated sign-ins via Entra ID are handled by Microsoft's own authentication — configure MFA on the Entra ID side if needed for those users.

Quick Reference

Imports

import { Cognito } from "@webiny/cognito";
import { CognitoIdpConfig } from "@webiny/cognito/api"; // for API config
import { CognitoSignInConfig } from "@webiny/cognito/admin"; // for Admin config

File Structure

extensions/entraid/
├── Extension.tsx       # Extension component with <Cognito federation={...} />
├── api.ts              # API config (role mapping) — optional
└── admin.tsx           # Admin config (login customization) — optional

Deploy Order

  1. yarn webiny deploy core --env=dev — creates Cognito IdP resources
  2. Update Entra ID redirect URI with the cognitoUserPoolDomain output
  3. yarn webiny deploy api --env=dev — deploys API with identity mapping
  4. yarn webiny deploy admin --env=dev — deploys admin with login screen

Related Skills

  • webiny-cognito-federation — Full reference for all Cognito Federation options
  • webiny-configure-okta — Alternative: Okta replaces Cognito entirely
  • webiny-configure-auth0 — Alternative: Auth0 replaces Cognito entirely

Version History

  • 80eb1c5 Current 2026-08-20 10:07

Same Skill Collection

.claude/skills/grill-me/SKILL.md
.claude/skills/prd-to-plan/SKILL.md
.claude/skills/preflight/SKILL.md
.claude/skills/tester/SKILL.md
.claude/skills/write-a-prd/SKILL.md
skills/repo-skills/add-feature-flag/SKILL.md
skills/user-skills/admin/admin-architect/SKILL.md
skills/user-skills/admin/admin-permissions/SKILL.md
skills/user-skills/admin/form-model/SKILL.md
skills/user-skills/admin/new-entry-wizard/SKILL.md
skills/user-skills/admin/website-builder/page-settings/SKILL.md
skills/user-skills/admin/website-builder/wb-preview-url-modifier/SKILL.md
skills/user-skills/api-bundle-size-limit/SKILL.md
skills/user-skills/api/api-architect/SKILL.md
skills/user-skills/api/cms-bulk-actions/SKILL.md
skills/user-skills/api/custom-field-type/SKILL.md
skills/user-skills/api/event-handler-pattern/SKILL.md
skills/user-skills/api/graphql-api/SKILL.md
skills/user-skills/api/http-route/SKILL.md
skills/user-skills/api/permissions/SKILL.md
skills/user-skills/api/use-case-pattern/SKILL.md
skills/user-skills/api/v5-to-v6-migration/SKILL.md
skills/user-skills/api/websocket-notifications/SKILL.md
skills/user-skills/cli-extensions/SKILL.md
skills/user-skills/configure-auth0/SKILL.md
skills/user-skills/configure-okta/SKILL.md
skills/user-skills/dependency-injection/SKILL.md
skills/user-skills/full-stack-architect/SKILL.md
skills/user-skills/generated/api/aco/SKILL.md
skills/user-skills/generated/api/cms/SKILL.md
skills/user-skills/generated/api/file-manager/SKILL.md
skills/user-skills/generated/api/scheduler/SKILL.md
skills/user-skills/generated/api/security/SKILL.md
skills/user-skills/generated/api/system/SKILL.md
skills/user-skills/generated/api/tenancy/SKILL.md
skills/user-skills/generated/api/tenant-manager/SKILL.md
skills/user-skills/generated/api/website-builder/SKILL.md
skills/user-skills/generated/infra/SKILL.md
skills/user-skills/infrastructure-extensions/SKILL.md
skills/user-skills/local-development/SKILL.md
skills/user-skills/mailer-smtp/SKILL.md
skills/user-skills/project-structure/SKILL.md
.claude/skills/webiny-skill-creator/SKILL.md
skills/user-skills/admin/ui-extensions/SKILL.md
skills/user-skills/api/ai-powerups-content/SKILL.md
skills/user-skills/cognito-federation/SKILL.md
skills/user-skills/content-models/SKILL.md
skills/user-skills/generated/admin/aco/SKILL.md
skills/user-skills/generated/admin/ai-powerups/SKILL.md

Metadata

Files
0
Version
80eb1c5
Hash
994bfd95
Indexed
2026-08-20 10:07

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-22 04:30
浙ICP备14020137号-1 $mapa de visitantes$