Azure B2C: REST call with external IDP - azure-ad-b2c

After configuring an external IDP in a user journey a subsequent REST call has to be made by sending an identifier to the REST endpoint. Upon receiving the response from the REST api, an attribute from the response has to be populated in the idtoken that has to be sent back to the caller.
The custom policy looks like this:
<ClaimsProvider>
<Domain>live.com</Domain>
<DisplayName>Microsoft Account</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="MSA-OIDC">
<DisplayName>Microsoft Account</DisplayName>
<Protocol Name="OpenIdConnect"/>
<Metadata>
<Item Key="ProviderName">https://login.live.com</Item>
<Item Key="METADATA">https://login.live.com/.well-known/openid-configuration</Item>
<Item Key="response_types">code</Item>
<Item Key="response_mode">form_post</Item>
<Item Key="scope">openid profile email</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">0</Item>
<Item Key="client_id">xxxxxxxxxx</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_MSASecret"/>
</CryptographicKeys>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
The REST call is like this:
curl --location --request GET 'https://swapi.dev/api/films/1/'
What I am looking for is a way to integrate the REST call with the user journey. Appreciate the responses.

This Azure AD B2C sample demonstrates how to log in to an external identity provider and then invoke a REST API.
An example of your user journey might be:
<UserJourney Id="SignUpOrSignIn">
<OrchestrationSteps>
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="MSA-OIDC" TechnicalProfileReferenceId="MSA-OIDC"/>
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="REST-GetFilm" TechnicalProfileReferenceId="REST-GetFilm"/>
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
</UserJourney>

Related

Get current password in Azure B2C XML Custom Policy

I need to retieve both the current password and the new password the user has set in a XML custom policy and pass that to an API endpoint.
Is this possible? I've tried to get the password using the Read operation of AAD-Common. I created a technical profile which successfully retrieves a custom attribute extension_RegisteredUserId, but if I add an output claim for the password I get the error:
New-AzureADMSTrustFrameworkPolicy : Error occurred while executing NewTrustFrameworkPolicy
Code: AADB2C
Message: Validation failed: 1 validation error(s) found in policy "B2C_1A_PASSWORDRESET" of tenant "rhsb2cdev.onmicrosoft.com".Output Claim 'password'
is not supported in Azure Active Directory Provider technical profile 'Get-RegisteredUserId' of policy 'B2C_1A_PasswordReset'. If it is a claim with
default value, add AlwaysUseDefaultValue="true" to the output claim mapping.Output Claim 'password' is not supported in Azure Active Directory Provider
technical profile 'Get-RegisteredUserId' of policy 'B2C_1A_PasswordReset'. If it is a claim with default value, add AlwaysUseDefaultValue="true" to the
output claim mapping.
InnerError:
RequestId: 3346b8e6-eaa7-4b51-9755-a08b2ce04860
DateTimeStamp: Tue, 14 Feb 2023 08:26:41 GMT
HttpStatusCode: BadRequest
This is my technical profile I use:
<TechnicalProfile Id="Get-RegisteredUserId">
<Metadata>
<Item Key="Operation">Read</Item>
<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>
<Item Key="UserMessageIfClaimsPrincipalDoesNotExist">An account could not be found for the provided user ID.</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" PartnerClaimType="signInNames.emailAddress" Required="true" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="objectId" />
<!-- This is ok -->
<OutputClaim ClaimTypeReferenceId="extension_RegisteredUserId" PartnerClaimType="extension_RegisteredUserId"/>
<!-- This is not ok -->
<OutputClaim ClaimTypeReferenceId="password" PartnerClaimType="password"/>
</OutputClaims>
<IncludeTechnicalProfile ReferenceId="AAD-Common" />
</TechnicalProfile>
which I call (in step 3 of the orchestration) prior to calling another technical profile that sends the extension_RegisteredUserId (and also should send the password) to an API (in step 4 of the orchestration). I can see the extension_RegisteredUserId getting sent across. Note also I do need to send the new password that they have chosen, if anyone has an idea of how to do this as well that would be great.
The user journey is this:
<UserJourney Id="PasswordReset">
<OrchestrationSteps>
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="GetRegisteredUserId" TechnicalProfileReferenceId="Get-RegisteredUserId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="Web-API-ChangePassword" TechnicalProfileReferenceId="REST-API-ChangePassword" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
<ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
The technical profile for the api call is this:
<!-- Custom Restful service -->
<TechnicalProfile Id="REST-API-ChangePassword">
<DisplayName>Registers a User on the Profile API</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ServiceUrl">(url for api)</Item>
<Item Key="AuthenticationType">None</Item>
<Item Key="SendClaimsIn">Body</Item>
<Item Key="AllowInsecureAuthInProduction">true</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="extension_RegisteredUserId" PartnerClaimType="registeredUserId"/>
<InputClaim ClaimTypeReferenceId="password" PartnerClaimType="oldPassword"/>
<InputClaim ClaimTypeReferenceId="newPassword" PartnerClaimType="newPassword"/>
</InputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
Any help would be very welcome. thank you

How to Use Send Grid to send a Confirmation Email with Azure B2C custom policy

I have a current policy that I need to send a confirmation email. I have a send grid account that is currently delivering a verification email and its working fine.
In my password reset flow, this is what I have.
<SubJourneys>
<SubJourney Id="PasswordReset" Type="Call">
<OrchestrationSteps>
<!-- Validate user's email address. -->
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PasswordResetUsingEmailAddressExchange" TechnicalProfileReferenceId="LocalAccountDiscoveryUsingEmailAddress" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Show TOU-->
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="SelfAssertedConsentExchange" TechnicalProfileReferenceId="SelfAsserted-PasswordResetConsent" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- Collect and persist a new password. -->
<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="NewCredentials" TechnicalProfileReferenceId="LocalAccountWritePasswordUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="GetAccessTokenPwdChangeNotification" TechnicalProfileReferenceId="SendPasswordChangeEmail" />
</ClaimsExchanges>
</OrchestrationStep>
</OrchestrationSteps>
</SubJourney>
In step one of this flow there is a verification email that takes place that uses send grid and it works fine.
step 4 is where the process seems to fail.
There is the technical profile for step 4
<ClaimsProvider>
<DisplayName>RestfulProvider</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="SendPasswordChangeEmail">
<DisplayName>Use SendGrid's email API to send the code the the 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://api.sendgrid.com/v3/mail/send</Item>
<Item Key="AuthenticationType">Bearer</Item>
<Item Key="SendClaimsIn">Body</Item>
<Item Key="ClaimUsedForRequestPayload">emailChangedBody</Item>
</Metadata>
<CryptographicKeys>
<Key Id="BearerAuthenticationToken" StorageReferenceId="B2C_1A_SendGridSecret" />
</CryptographicKeys>
<InputClaimsTransformations>
<InputClaimsTransformation ReferenceId="GenerateEmailChangedBody" />
</InputClaimsTransformations>
<InputClaims>
<InputClaim ClaimTypeReferenceId="emailChangedBody" />
</InputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
That references this claims transformation.
<ClaimsTransformation Id="GenerateEmailChangedBody" TransformationMethod="GenerateJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="email" TransformationClaimType="personalizations.0.to.0.email" />
</InputClaims>
<InputParameters>
<!-- Update the template_id value with the ID of your SendGrid template. -->
<InputParameter Id="template_id" DataType="string" Value="my template"/>
<InputParameter Id="from.email" DataType="string" Value="my email"/>
<!-- Update with a subject line appropriate for your organization. -->
<InputParameter Id="personalizations.0.dynamic_template_data.subject" DataType="string" Value="Account Password Changed"/>
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="emailChangedBody" TransformationClaimType="outputClaim"/>
</OutputClaims>
</ClaimsTransformation>
I am getting a bad request when this goes out.
My ONLY guess is that the email is not getting passed into that claims transformation so it does not know where to send the email.
Any help would be appreicated.

Azure B2C call azure function with JWT token or code kept as policy key

is it possible to call azure function without hardcoding function code in service url?
For example using policy key and sending it as query string/header. I don't want it to be exposed.
Alternative is to use AAD auth on app service level, but that would require generating JWT token before step "SendClaims" and it could possibly led to authenticated users having access to this function.
Thanks for any help.
Edit:
Ok, I did it as suggested and I got to a point where I have everything set up.
I can request a working token using postman and authorize properly to azure function.
I have debugged said token in user journey by outputting it as user claim (I confirmed that acquire step is working), but I get an error on calling function
AADB2C90027: Basic credentials specified for 'Azure-Functions-Notify-New-User-Registered' are invalid. Check that the credentials are correct and that access has been granted by the resource.
So far my xml file looks like that:
<ClaimsProvider>
<DisplayName>Aquire JWT token to call azure function</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="Azure-Functions-Notify-New-User-Registered-AccessToken">
<DisplayName>Acquire JWT token to call azure function</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://login.microsoftonline.com/{my-tenant}/oauth2/v2.0/token</Item>
<Item Key="AuthenticationType">Basic</Item>
<Item Key="SendClaimsIn">Form</Item>
</Metadata>
<CryptographicKeys>
<Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_NotifyNewUserRegisteredClientId" />
<Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_NotifyNewUserRegisteredSecret" />
</CryptographicKeys>
<InputClaims>
<InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="client_credentials" AlwaysUseDefaultValue="true" />
<InputClaim ClaimTypeReferenceId="scope" DefaultValue="https://{my-tenant}/{my-resoruce-id}/.default" AlwaysUseDefaultValue="true" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="bearerToken" PartnerClaimType="access_token" />
</OutputClaims>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
<ClaimsProvider>
<DisplayName>Azure-Functions-Notify-New-User-Registered</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="Azure-Functions-Notify-New-User-Registered">
<DisplayName>Call Azure Function when new user registers</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="ServiceUrl">{my-azure-function-with-function-code}</Item>
<Item Key="SendClaimsIn">Body</Item>
<Item Key="AuthenticationType">Bearer</Item>
<Item Key="UseClaimAsBearerToken">bearerToken</Item>
<Item Key="AllowInsecureAuthInProduction">false</Item>
</Metadata>
<InputClaims>
<InputClaim ClaimTypeReferenceId="bearerToken"/>
</InputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
And my user journey:
<OrchestrationStep Order="7" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="Azure-Functions-Notify-New-User-Registered-AccessToken" TechnicalProfileReferenceId="Azure-Functions-Notify-New-User-Registered-AccessToken" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="8" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="Azure-Functions-Notify-New-User-Registered" TechnicalProfileReferenceId="Azure-Functions-Notify-New-User-Registered" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="9" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
Protect it with AAD. Get the JWT to the function app using this:
https://learn.microsoft.com/en-us/azure/active-directory-b2c/secure-rest-api#oauth2-bearer-authentication
No you don’t need to worry about the user getting this JWT, that’s impossible unless you decide to output this JWT as a claim in the relying party section.

Login screen showing again while accessing profile edit policy after user login in App Azure AD B2C

I'm asking this behalf of one mobile/web developer, i have created some custom policies in AD B2C. Now the developer is trying to integrate this with an application. For some reason i have used:
<DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:1.2.0
</DataUri>
as the data uri for signin techinical profile. And content defenition is:
<ContentDefinition Id="api.localaccount.login">
<LoadUri>my custom html</LoadUri>
<RecoveryUri>~/common/default_page_error.html</RecoveryUri>
<DataUri>urn:com:microsoft:aad:b2c:elements:contract:selfasserted:1.2.0</DataUri>
<Metadata>
<Item Key="DisplayName">Local Account Login</Item>
</Metadata>
<LocalizedResourcesReferences MergeBehavior="Prepend">
<LocalizedResourcesReference Language="en" LocalizedResourcesReferenceId="signin_en" />
<LocalizedResourcesReference Language="es" LocalizedResourcesReferenceId="signin_es" />
</LocalizedResourcesReferences>
</ContentDefinition>
Login TP:
<TechnicalProfile Id="SelfAsserted-LocalAccountSignin-CustomUserName-WithoutSignup">
<DisplayName>Local Account Signin UserName</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<Metadata>
<Item Key="setting.operatingMode">Username</Item>
<Item Key="setting.retryLimit">11</Item>
<Item Key="ContentDefinitionReferenceId">api.localaccount.login</Item>
<Item Key="UserMessageIfUserAccountDisabled">You account locked.</Item>
<Item Key="UserMessageIfUserAccountLocked">You've made too many incorrect attempts. Please try again later.</Item>
<Item Key="setting.showCancelButton">false</Item>
<Item Key="language.button_continue">LOG IN</Item>
<Item Key="ServiceThrottled">There are too many requests at this moment. Please wait for some time and try again.</Item>
</Metadata>
<IncludeInSso>false</IncludeInSso>
<InputClaims>
<InputClaim ClaimTypeReferenceId="signInName" />
</InputClaims>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
<OutputClaim ClaimTypeReferenceId="password" Required="true" />
<OutputClaim ClaimTypeReferenceId="objectId" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" />
<OutputClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" DefaultValue="false" />
</OutputClaims>
<ValidationTechnicalProfiles>
<ValidationTechnicalProfile ReferenceId="CheckUserExist" />
<ValidationTechnicalProfile ReferenceId="SendOTP" />
<ValidationTechnicalProfile ReferenceId="login-NonInteractive" />
</ValidationTechnicalProfiles>
</TechnicalProfile>
And my user journey is as follows:
<UserJourneys>
<UserJourney Id="OnBoarding">
<OrchestrationSteps>
<OrchestrationStep Order="1" Type="ClaimsProviderSelection" ContentDefinitionReferenceId="api.idpselections">
<ClaimsProviderSelections>
<ClaimsProviderSelection TargetClaimsExchangeId="LocalAccountSigninEmailExchange" />
</ClaimsProviderSelections>
</OrchestrationStep>
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-CustomUserName-WithoutSignup" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="4" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="B2CUserProfileUpdateExchange" TechnicalProfileReferenceId="SelfAsserted-AccountValueUpdate" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="5" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadUserWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="6" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
<ClientDefinition ReferenceId="DefaultWeb" />
</UserJourney>
</UserJourneys>
Policy works fine and when he tries to integrate it with replying party app, after user signup profile update journey called (above user journey), but it is showing the login screen again. How can bypass the login after registration? Is this something that we need to with policy?
Edit:
I'm using separate policies for sign in and sign up. After signin journey works as expected, but after signup the login screen comes.
Look at the starter pack again, you have removed the Session management technical profile reference (SM-AAD) from your sign in page. So during profile edit it won’t get skipped for a signed in user.
https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/blob/master/LocalAccounts/TrustFrameworkBase.xml#L687

Azure AD B2C - Refresh_Token refresh claims via REST (Identity Experience Framework)

We have Azure AD B2C setup to use Identity Experience Framework, and on sign-in/sign-up a REST call is made to get extra security credential claims via an Azure Function. This works fine.
When we request an Access/Id Token via Refresh_Token via Azure AD B2C it looks like we get the same token back, and it doesn't call the REST API to get the latest updated token claims. Is it possible to make change this User Journey so it does?
Is there another solution to refresh token without logging in again to get latest updates?
(We could get around this in code and not using the Token, but for various reasons we want to explore this first).
You can declare a refresh token user journey, which calls your REST API, as follows:
<UserJourney Id="TokenRefresh">
<PreserveOriginalAssertion>false</PreserveOriginalAssertion>
<OrchestrationSteps>
<OrchestrationStep Order="1" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="RefreshTokenExchange" TechnicalProfileReferenceId="TpEngine_RefreshToken" />
</ClaimsExchanges>
</OrchestrationStep>
<OrchestrationStep Order="2" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="AADUserReadWithObjectId" TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
</ClaimsExchanges>
</OrchestrationStep>
<!-- TODO: Add an orchestration step that calls the REST API. -->
<OrchestrationStep Order="3" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
</OrchestrationSteps>
</UserJourney>
The initial orchestration step invokes the TpEngine_RefreshToken technical profile that reads the objectId claim from the current refresh token:
<ClaimsProvider>
<DisplayName>Trustframework Policy Engine Technical Profiles</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="TpEngine_c3bd4fe2-1775-4013-b91d-35f16d377d13">
<DisplayName>Trustframework Policy Engine Default Technical Profile</DisplayName>
<Protocol Name="None" />
<Metadata>
<Item Key="url">{service:te}</Item>
</Metadata>
</TechnicalProfile>
<TechnicalProfile Id="TpEngine_RefreshToken">
<DisplayName>Trustframework Policy Engine Refresh Token Technical Profile</DisplayName>
<Protocol Name="None" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="objectId" />
</OutputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
The second orchestration step invokes the AAD-UserReadUsingObjectId technical profile that reads claims from the Azure AD B2C directory for the signed-in user by the objectId claim.
Another orchestration step can call your REST API.
The final orchestration step issues new tokens.
You must reference the TokenRefresh user journey using the RefreshTokenUserJourneyId metadata item with the JwtIssuer technical profile so that tokens that are issued by this technical profile are refreshed by this user journey:
<ClaimsProvider>
<DisplayName>Token Issuer</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="JwtIssuer">
<DisplayName>JWT Issuer</DisplayName>
<Protocol Name="None" />
<OutputTokenFormat>JWT</OutputTokenFormat>
<Metadata>
<Item Key="client_id">{service:te}</Item>
<Item Key="issuer_refresh_token_user_identity_claim_type">objectId</Item>
<Item Key="RefreshTokenUserJourneyId">TokenRefresh</Item>
<Item Key="SendTokenResponseBodyWithJsonNumbers">true</Item>
</Metadata>
<CryptographicKeys>
<Key Id="issuer_secret" StorageReferenceId="B2C_1A_TokenSigningKeyContainer" />
<Key Id="issuer_refresh_token_key" StorageReferenceId="B2C_1A_TokenEncryptionKeyContainer" />
</CryptographicKeys>
<InputClaims />
<OutputClaims />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>

Resources