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 . It is referenced by other technical profiles.
<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) documentation.
Init Auth API
The POST /init-auth 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
.
User Journey Orchestration Step Technical Profile Input Claims Transformation Claims <OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AuthsignalOidcInitAuth" TechnicalProfileReferenceId="AuthsignalOidcInitAuth"/>
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AuthsignalOidcInitAuth" TechnicalProfileReferenceId="AuthsignalOidcInitAuth"/>
</ClaimsExchanges>
</OrchestrationStep>
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 documentation for the full list of available inputs.
<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>
<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" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="requestBody" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
<ClaimType Id="requestBody">
<DisplayName>requestBody</DisplayName>
<DataType>string</DataType>
</ClaimType>
<ClaimType Id="bearerToken">
<DisplayName>bearerToken</DisplayName>
<DataType>string</DataType>
</ClaimType>
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.
OIDC Authorize API
The GET /oidc/auth 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.
User Journey Orchestration Steps Technical Profile Output Claims Transformation Claims <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>
<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>
<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>
<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>
<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>
This step must always be performed after the AuthsignalOidcInitAuth
orchestration step
Utility Endpoints
These API calls extend on the above Base Technical Profile which sets the required authorization headers.
Authsignal has a core server API which can be invoked using the Azure AD 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 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.
User Journey Orchestration Step Technical Profile Input Claims Transformation Claims <OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AuthsignalGetUser" TechnicalProfileReferenceId="AuthsignalGetUser" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AuthsignalGetUser" TechnicalProfileReferenceId="AuthsignalGetUser" />
</ClaimsExchanges>
</OrchestrationStep>
<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>
<ClaimsTransformation Id="AuthsignaCreateGetUserRequestBody" TransformationMethod="GenerateJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="userId" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="getUserRequestBody" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
<ClaimType Id="getUserRequestBody">
<DisplayName>getUserRequestBody</DisplayName>
<DataType>string</DataType>
</ClaimType>
<ClaimType Id="isEnrolled">
<DisplayName>isEnrolled</DisplayName>
<DataType>boolean</DataType>
</ClaimType>