-
Notifications
You must be signed in to change notification settings - Fork 1
feat(oidc): add Azure AD B2C OpenID Connect Provider #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
halvaradop
wants to merge
1
commit into
master
Choose a base branch
from
feat/add-azure-dir-b2c-oidc
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,196 @@ | ||
| --- | ||
| title: Azure AD B2C | ||
| description: Add Azure AD B2C authorization provider to Aura Auth for authentication and authorization | ||
| --- | ||
|
|
||
| <Steps> | ||
|
|
||
| <Step> | ||
|
|
||
| ## Azure AD B2C OAuth App | ||
|
|
||
| ### Register the Application | ||
|
|
||
| The first step is to create and register an OAuth App on the Azure AD B2C Applications to obtain access to the user's resources. | ||
|
|
||
| </Step> | ||
|
|
||
| <Step> | ||
|
|
||
| ## Installation | ||
|
|
||
| Install the package using a package manager like `npm`, `pnpm`, or `yarn`: | ||
|
|
||
| ```npm | ||
| npm install @aura-stack/auth | ||
| ``` | ||
|
|
||
| </Step> | ||
|
|
||
| <Step> | ||
|
|
||
| ## Environment setup | ||
|
|
||
| Now, you must configure the environment variables required by Aura Auth, including the Azure AD B2C credentials and the encryption secrets. | ||
|
|
||
| ```bash title=".env" lineNumbers | ||
| # Aura Secrets | ||
| AURA_AUTH_SECRET="your-32-byte-secret" | ||
| AURA_AUTH_SALT="your-32-byte-salt" | ||
|
|
||
| # Azure AD B2C Credentials | ||
| AURA_AUTH_AZURE_AD_B2C_CLIENT_ID="your_azure_ad_b2c_client_id" | ||
| AURA_AUTH_AZURE_AD_B2C_CLIENT_SECRET="your_azure_ad_b2c_client_secret" | ||
| ``` | ||
|
|
||
| <Callout type="warn"> | ||
| **CRITICAL SECURITY WARNING:** The `AURA_AUTH_SECRET` and `AURA_AUTH_SALT` variables are used to encrypt and sign user sessions. | ||
| These MUST be securely generated, highly randomized strings consisting of at least 32 bytes to ensure adequate entropy. Never | ||
| hardcode these values in your repository. Use a secure generator (like `openssl rand -base64 32`) to create them, and store them | ||
| exclusively in your secure environment variables manager. | ||
| </Callout> | ||
|
|
||
| </Step> | ||
|
|
||
| <Step> | ||
|
|
||
| ## Configure the Auth Instance | ||
|
|
||
| Configure the `createAuth` instance inside an `auth.ts` file located at the root of your project. Ensure you explicitly export the `handlers`, `api`, and `jose` objects. | ||
|
|
||
| ```ts title="auth.ts" lineNumbers | ||
| import { createAuth } from "@aura-stack/auth" | ||
|
|
||
| export const auth = createAuth({ | ||
| oauth: ["azure-ad-b2c"], | ||
| }) | ||
|
|
||
| // Extract the required utilities | ||
| export const { handlers, api, jose } = auth | ||
| ``` | ||
|
|
||
| <Callout type="info"> | ||
| The `handlers` object contains mapping utilities for standard HTTP methods (`GET`, `POST`, `PATCH`) as well as a unified `ALL` | ||
| handler. This allows you to easily mount the authentication routes across any framework (Next.js, Elysia, Express, etc.). | ||
| </Callout> | ||
|
|
||
| </Step> | ||
|
|
||
| <Step> | ||
|
|
||
| ## Customizing the OAuth Provider | ||
|
|
||
| If you need to define custom scopes, change the response type, or map profile data differently, you can use the provider's factory function instead of a simple string identifier. | ||
|
|
||
| ```ts title="auth.ts" lineNumbers | ||
| import { createAuth } from "@aura-stack/auth" | ||
| import { azureADB2C } from "@aura-stack/auth/oauth/azure-ad-b2c" | ||
|
|
||
| export const auth = createAuth({ | ||
| oauth: [ | ||
| azureADB2C({ | ||
| authorize: { | ||
| params: { | ||
| // Override default scopes | ||
| scope: "read:user user:email", | ||
| }, | ||
| }, | ||
| }), | ||
| ], | ||
| }) | ||
|
|
||
| export const { handlers, api, jose } = auth | ||
| ``` | ||
|
halvaradop marked this conversation as resolved.
|
||
|
|
||
| </Step> | ||
|
|
||
| <Step> | ||
|
|
||
| ## Sign In to Azure AD B2C (Client & Server) | ||
|
|
||
| There are multiple ways to trigger the sign-in flow depending on your ecosystem. | ||
|
|
||
| ### Sign-in Path (Direct Navigation) | ||
|
|
||
| The common route to trigger the auth flow natively without needing a client library is simply navigating the browser to: | ||
| `http://localhost:3000/auth/signIn/azure-ad-b2c` | ||
|
|
||
| --- | ||
|
|
||
| ### Client-Side (React, Vue, etc.) | ||
|
|
||
| You can utilize the `createAuthClient` utility to programmatically trigger sign-ins. You can also define a `redirectTo` destination. | ||
|
|
||
| <Callout type="warn"> | ||
| **Constraint Rule**: The `baseURL` passed into `createAuthClient` MUST exactly match the root domain and path where the HTTP | ||
| `handlers` expose their endpoints on the server. | ||
| </Callout> | ||
|
|
||
| ```ts title="components/Login.tsx" lineNumbers | ||
| import { createAuthClient } from "@aura-stack/auth/client" | ||
|
|
||
| export const authClient = createAuthClient({ | ||
| baseURL: "http://localhost:3000/auth", | ||
| }) | ||
|
|
||
| const triggerSignIn = async () => { | ||
| await authClient.signIn("azure-ad-b2c", { | ||
| redirectTo: "/dashboard", | ||
| }) | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### Server-Side (Next.js Actions, Remix Loaders, etc.) | ||
|
|
||
| For environments supporting server-side actions, use the programmatic `api.signIn` method securely. | ||
|
|
||
| ```ts title="actions.ts" lineNumbers | ||
| import { api } from "./auth" | ||
|
|
||
| export const serverSignIn = async () => { | ||
| const response = await api.signIn("azure-ad-b2c", { | ||
| redirectTo: "http://localhost:3000/dashboard", | ||
| }) | ||
|
|
||
| // Example returning redirect location | ||
| return response.headers.get("Location") | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### Session Retrieval | ||
|
|
||
| After a user successfully signs in, you can retrieve their session data securely. | ||
|
|
||
| **Client-Side:** | ||
|
|
||
| ```ts | ||
| const session = await authClient.getSession() | ||
| console.log(session?.user) // The authenticated Azure AD B2C user profile | ||
| ``` | ||
|
|
||
| **Server-Side:** | ||
|
|
||
| ```ts | ||
| // Note: You must pass the native Web Request object or Headers! | ||
| const session = await api.getSession(request) | ||
| console.log(session?.user) // Safely retrieved backend session | ||
| ``` | ||
|
|
||
| </Step> | ||
|
|
||
| </Steps> | ||
|
|
||
| --- | ||
|
|
||
| ## Resources | ||
|
|
||
| - [RFC - The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749) | ||
| - [Azure Active Directory B2C - OAuth 2.0 Provider](https://learn.microsoft.com/en-us/azure/active-directory-b2c/) | ||
| - [Azure Active Directory B2C - Authorization Code Flow](https://learn.microsoft.com/en-us/azure/active-directory-b2c/authorization-code-flow) | ||
| - [Azure Active Directory B2C - Register a web application](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications) | ||
| - [Azure Active Directory B2C - Request an access token](https://learn.microsoft.com/en-us/azure/active-directory-b2c/access-tokens) | ||
| - [Azure Active Directory B2C - Claims](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview#claims) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| import type { OAuthProviderCredentials, User } from "@/@types/index.ts" | ||
|
|
||
| /** | ||
| * @see [Azure Active Directory B2C - Claims](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview#claims) | ||
| */ | ||
| export interface AzureADB2CProfile { | ||
| aud: string | ||
| iss: string | ||
| iat: number | ||
| exp: number | ||
| nbf: number | ||
| ver: string | ||
| c_hash: string | ||
| at_hash: string | ||
| nonce: string | ||
| sub: string | ||
| acr: string | ||
| auth_time: number | ||
| scp: string | ||
| azp: string | ||
| email: string | ||
| email_verified: boolean | ||
| name: string | ||
| given_name: string | ||
| family_name: string | ||
| preferred_username: string | ||
| nickname: string | ||
| } | ||
|
|
||
| /** | ||
| * Azure ActiveDirectory B2C OpenID Connect Provider | ||
| * | ||
| * > Should set the tenant and policy values in the authorize URL and access token URL.: | ||
| * > - https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize | ||
| * > - https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token | ||
| * | ||
| * @todo Investigate what does https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/b2c_1_sign_in/v2.0/.well-known/openid-configuration URL | ||
| * | ||
| * @see [Azure Active Directory B2C - OAuth 2.0 Provider](https://learn.microsoft.com/en-us/azure/active-directory-b2c/) | ||
| * @see [Azure Active Directory B2C - Authorization Code Flow](https://learn.microsoft.com/en-us/azure/active-directory-b2c/authorization-code-flow) | ||
| * @see [Azure Active Directory B2C - Register a web application](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications) | ||
| * @see [Azure Active Directory B2C - Request an access token](https://learn.microsoft.com/en-us/azure/active-directory-b2c/access-tokens) | ||
| * @see [Azure Active Directory B2C - Claims](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tokens-overview#claims) | ||
| */ | ||
| export const azureADB2C = <DefaultUser extends User = User>( | ||
| options?: Partial<OAuthProviderCredentials<AzureADB2CProfile, DefaultUser>> | ||
| ): OAuthProviderCredentials<AzureADB2CProfile, DefaultUser> => { | ||
| return { | ||
| id: "azure-ad-b2c", | ||
| name: "Azure AD B2C", | ||
| authorize: { | ||
| url: "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize", | ||
| params: { scope: "profile email" }, | ||
| }, | ||
| accessToken: "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token", | ||
| userInfo: "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/openid-configuration", | ||
| profile: (profile) => | ||
| ({ | ||
| sub: profile.sub, | ||
| name: profile.name, | ||
| email: profile.email, | ||
| image: null, | ||
| }) as DefaultUser, | ||
| ...options, | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.