> ## Documentation Index
> Fetch the complete documentation index at: https://docs.authsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Microsoft Azure AD B2C Custom Policy Snippets

> Use Authsignal custom policy snippets to customize Microsoft Azure AD B2C flows.

## Base Technical Profile

This is the base technical profile that is used to connect to the Authsignal Connect (OIDC) API by setting the authorization header, request body and other necessary configuration for the [Azure AD B2C's RestfulProvider](https://learn.microsoft.com/en-us/azure/active-directory-b2c/restful-technical-profile). It is referenced by other technical profiles.

```xml theme={null}
<TechnicalProfile Id="AuthsignalConnectApiBase">
    <DisplayName>Authsignal Connect API Base</DisplayName>
    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    <Metadata>
        <Item Key="SendClaimsIn">Body</Item>
        <Item Key="AuthenticationType">Basic</Item>
        <Item Key="AllowInsecureAuthInProduction">false</Item>
        <Item Key="ResolveJsonPathsInJsonTokens">true</Item>
        <Item Key="ClaimUsedForRequestPayload">requestBody</Item>
        <Item Key="DefaultUserMessageIfRequestFailed">Cannot process your request right now, please try again later.</Item>
    </Metadata>
    <CryptographicKeys>
        <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_AuthsignalSecret" />
        <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_AuthsignalSecret" />
    </CryptographicKeys>
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="requestBody" />
    </InputClaims>
</TechnicalProfile>
```

## OpenID Connect (OIDC) Endpoints

The following technical profiles are used to interact with the Authsignal Connect API using the OpenID Connect (OIDC) protocol.

An explanation of the integration model can be found in [Authsignal's Open ID Connect (OIDC)](/integrations/oidc) documentation.

### Init Auth API

The [POST /init-auth](/integrations/oidc#init-endpoint) endpoint must be called before federating the flows to Authsignal via the OIDC Authorize technical profile.

Through the input claims, we pass in the user identifier, the Authsignal action being performed, and any other customizations such as `redirectToSettings`.

<Tabs>
  <Tab title="User Journey Orchestration Step">
    ```xml theme={null}
    <OrchestrationStep Order="4" Type="ClaimsExchange">
        <ClaimsExchanges>
            <ClaimsExchange Id="AuthsignalOidcInitAuth" TechnicalProfileReferenceId="AuthsignalOidcInitAuth"/>
        </ClaimsExchanges>
    </OrchestrationStep>
    ```
  </Tab>

  <Tab title="Technical Profile">
    The init-auth endpoint only requires an `userId` and an `action`.
    Other inputs are optional but can be used to customize the behavior of Authsignal's pre-built UI, such as redirecting the users to manage their authenticator settings post authentication.

    Refer to the [POST /init-auth](/integrations/oidc#init-endpoint) documentation for the full list of available inputs.

    ```xml theme={null}
    <TechnicalProfile Id="AuthsignalOidcInitAuth">
        <DisplayName>Authsignal OIDC Init Auth API</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        <!-- NOTE: Change the host name below -->
        <Metadata>
            <Item Key="ServiceUrl">https://AUTHSIGNAL_CONNECT_HOSTNAME/init-auth</Item>
        </Metadata>
        <InputClaimsTransformations>
            <InputClaimsTransformation ReferenceId="AuthsignalCreateInitAuthRequestBody"/>
        </InputClaimsTransformations>
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="requestBody"/>
        </InputClaims>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="bearerToken" PartnerClaimType="token"/>
        </OutputClaims>
        <IncludeTechnicalProfile ReferenceId="AuthsignalConnectApiBase"/>
    </TechnicalProfile>
    ```
  </Tab>

  <Tab title="Input Claims Transformation">
    ```xml theme={null}
    <ClaimsTransformation Id="AuthsignalCreateInitAuthRequestBody" TransformationMethod="GenerateJson">
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="userId" />
            <InputClaim ClaimTypeReferenceId="signInNames.emailAddress" TransformationClaimType="email" />
        </InputClaims>
        <InputParameters>
            <!-- NOTE: Change the action value here to the corresponding Authsignal action your user is performing. This may be signIn, signUp, manageSettings etc. -->
            <InputParameter Id="action" DataType="string" Value="INSERT_AUTHSIGNAL_ACTION" />
            <InputParameter Id="redirectToSettings" DataType="boolean" Value="false" />
            <!-- When true, syncs the user's email authenticator to the email address verified by Azure AD B2C -->
            <InputParameter Id="emailVerified" DataType="boolean" Value="true" />
        </InputParameters>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="requestBody" TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>
    ```
  </Tab>

  <Tab title="Claims">
    ```xml theme={null}
    <ClaimType Id="requestBody">
        <DisplayName>requestBody</DisplayName>
        <DataType>string</DataType>
    </ClaimType>

    <ClaimType Id="bearerToken">
        <DisplayName>bearerToken</DisplayName>
        <DataType>string</DataType>
    </ClaimType>
    ```
  </Tab>
</Tabs>

<Info>
  Note that the Authsignal OIDC endpoints should only be called when you have
  identified the user, but before the user is authenticated and is issued a
  token. These snippets are dependent on `objectId` which is an output claim of
  the default Azure AD B2C self-asserted technical profiles.
</Info>

### OIDC Authorize API

The [GET /oidc/auth](/integrations/oidc#oidc-authorize-endpoint) endpoint is used to begin the authentication flow with Authsignal. The token returned by the previous init-auth endpoint will be used in this endpoint.

<Tabs>
  <Tab title="User Journey Orchestration Steps">
    ```xml theme={null}
    <OrchestrationStep Order="5" Type="ClaimsExchange">
       <ClaimsExchanges>
           <ClaimsExchange Id="AuthsignalOidcAuth" TechnicalProfileReferenceId="AuthsignalOidcAuth"/>
       </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="6" Type="ClaimsExchange">
       <Preconditions>
       <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
           <Value>isMatchingUserId</Value>
           <Value>True</Value>
           <Action>SkipThisOrchestrationStep</Action>
       </Precondition>
       </Preconditions>
       <ClaimsExchanges>
           <ClaimsExchange Id="ShowUserIdMismatchErrorPage" TechnicalProfileReferenceId="SelfAsserted-Error" />
       </ClaimsExchanges>
    </OrchestrationStep>

    <OrchestrationStep Order="7" Type="ClaimsExchange">
       <Preconditions>
       <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
           <Value>isChallengeSuccessful</Value>
           <Value>true</Value>
           <Action>SkipThisOrchestrationStep</Action>
       </Precondition>
       </Preconditions>
       <ClaimsExchanges>
           <ClaimsExchange Id="ShowChallengeFailedPage" TechnicalProfileReferenceId="SelfAsserted-Error" />
       </ClaimsExchanges>
    </OrchestrationStep>
    ```
  </Tab>

  <Tab title="Technical Profile">
    ```xml theme={null}
    <TechnicalProfile Id="AuthsignalOidcAuth">
        <DisplayName>Authsignal OIDC Authorize API</DisplayName>
        <Protocol Name="OpenIdConnect" />
        <Metadata>
            <!-- NOTE: Change the host name and tenant id below -->
            <Item Key="METADATA">https://AUTHSIGNAL_CONNECT_HOSTNAME/oidc/.well-known/openid-configuration</Item>
            <Item Key="client_id">INSERT_AUTHSIGNAL_TENANT_ID</Item>
            <Item Key="authorization_endpoint">https://AUTHSIGNAL_CONNECT_HOSTNAME/oidc/auth</Item>
            <Item Key="AccessTokenEndpoint">https://AUTHSIGNAL_CONNECT_HOSTNAME/oidc/token</Item>
            <Item Key="response_types">code</Item>
            <Item Key="scope">openid</Item>
            <Item Key="HttpBinding">POST</Item>
            <Item Key="response_mode">form_post</Item>
            <Item Key="token_endpoint_auth_method">client_secret_post</Item>
            <Item Key="UsePolicyInRedirectUri">false</Item>
            <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
            <Item Key="ResolveJsonPathsInJsonTokens">true</Item>
        </Metadata>
        <CryptographicKeys>
            <Key Id="client_secret" StorageReferenceId="B2C_1A_AuthsignalSecret" />
        </CryptographicKeys>
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="bearerToken" PartnerClaimType="token" />
        </InputClaims>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="actionCode" PartnerClaimType="action_code" />
            <OutputClaim ClaimTypeReferenceId="actionState" PartnerClaimType="action_state" />
            <OutputClaim ClaimTypeReferenceId="authsignalUserId" PartnerClaimType="sub" />
            <OutputClaim ClaimTypeReferenceId="authsignalEnrolled" PartnerClaimType="is_enrolled" />
        </OutputClaims>
        <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="AuthsignalCheckIsChallengeSuccessful" />
            <OutputClaimsTransformation ReferenceId="AuthsignalCheckMatchingUserId" />
        </OutputClaimsTransformations>
    </TechnicalProfile>
    ```
  </Tab>

  <Tab title="Output Claims Transformation">
    ```xml theme={null}
    <ClaimsTransformation Id="AuthsignalCheckMatchingUserId" TransformationMethod="CompareClaims">
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="inputClaim1" />
            <InputClaim ClaimTypeReferenceId="authsignalUserId" TransformationClaimType="inputClaim2" />
        </InputClaims>
        <InputParameters>
            <InputParameter Id="operator" DataType="string" Value="EQUAL" />
            <InputParameter Id="ignoreCase" DataType="string" Value="true" />
        </InputParameters>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="isMatchingUserId" TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>

    <ClaimsTransformation Id="AuthsignalCheckIsChallengeSuccessful" TransformationMethod="LookupValue">
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="actionState" TransformationClaimType="inputParameterId" />
        </InputClaims>
        <InputParameters>
            <InputParameter Id="ALLOW" DataType="string" Value="true" />
            <InputParameter Id="CHALLENGE_SUCCEEDED" DataType="string" Value="true" />
            <InputParameter Id="CHALLENGE_FAILED" DataType="string" Value="false" />
            <InputParameter Id="BLOCK" DataType="string" Value="false" />
            <InputParameter Id="errorOnFailedLookup" DataType="boolean" Value="false" />
        </InputParameters>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="isChallengeSuccessful" TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>
    ```
  </Tab>

  <Tab title="Claims">
    ```xml theme={null}
    <ClaimType Id="actionCode">
        <DisplayName>actionCode</DisplayName>
        <DataType>string</DataType>
    </ClaimType>

    <ClaimType Id="actionState">
        <DisplayName>actionState</DisplayName>
        <DataType>string</DataType>
    </ClaimType>

    <ClaimType Id="isMatchingUserId">
        <DataType>boolean</DataType>
    </ClaimType>

    <ClaimType Id="isChallengeSuccessful">
        <DataType>string</DataType>
    </ClaimType>

    <ClaimType Id="authsignalUserId">
        <DataType>string</DataType>
    </ClaimType>
    ```
  </Tab>
</Tabs>

<Info>
  This step must always be performed after the `AuthsignalOidcInitAuth`
  orchestration step
</Info>

## Utility Endpoints

These API calls extend on the above [Base Technical Profile](#base-technical-profile) which sets the required authorization headers.

Authsignal has a core [server API](/api-reference/server-api/overview) which can be invoked using the [Azure AD B2C RESTful technical profile](https://learn.microsoft.com/en-us/azure/active-directory-b2c/restful-technical-profile).

Due to Azure AD B2C technical profiles being restricted to setting input claims in either the url or body and not both, we've created convenience proxy endpoints to map to our key APIs.

### Get user

The following code snippets map to our [Get User](/api-reference/server-api/get-user) API call.

The policies only use the `isEnrolled` property from the response, but you can extend this to include other claims as needed.

`isEnrolled` is `true` if the user is enrolled with at least one verification method and can be challenged.

<Tabs>
  <Tab title="User Journey Orchestration Step">
    ```xml theme={null}
     <OrchestrationStep Order="1" Type="ClaimsExchange">
         <ClaimsExchanges>
             <ClaimsExchange Id="AuthsignalGetUser" TechnicalProfileReferenceId="AuthsignalGetUser" />
         </ClaimsExchanges>
     </OrchestrationStep>
    ```
  </Tab>

  <Tab title="Technical Profile">
    ```xml theme={null}
    <TechnicalProfile Id="AuthsignalGetUser">
        <DisplayName>Authsignal Get User</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
            <Item Key="ServiceUrl">https://AUTHSIGNAL_CONNECT_HOSTNAME/get-user</Item>
        </Metadata>
        <InputClaimsTransformations>
            <InputClaimsTransformation ReferenceId="AuthsignaCreateGetUserRequestBody" />
        </InputClaimsTransformations>
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="getUserRequestBody" />
        </InputClaims>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="isEnrolled" PartnerClaimType="isEnrolled" />
        </OutputClaims>
        <IncludeTechnicalProfile ReferenceId="AuthsignalConnectApiBase" />
    </TechnicalProfile>
    ```
  </Tab>

  <Tab title="Input Claims Transformation">
    ```xml theme={null}
    <ClaimsTransformation Id="AuthsignaCreateGetUserRequestBody" TransformationMethod="GenerateJson">
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="userId" />
        </InputClaims>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="getUserRequestBody" TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>
    ```
  </Tab>

  <Tab title="Claims">
    ```xml theme={null}
    <ClaimType Id="getUserRequestBody">
        <DisplayName>getUserRequestBody</DisplayName>
        <DataType>string</DataType>
    </ClaimType>

    <ClaimType Id="isEnrolled">
        <DisplayName>isEnrolled</DisplayName>
        <DataType>boolean</DataType>
    </ClaimType>
    ```
  </Tab>
</Tabs>
