0

When a user logs in, I hit a REST API that verifies the username and password and returns some properties like personId, comUsername, wcfToken, and organizationCode. These properties are then returned to the user as an access token.

This is how my Access token looks like on the initial login enter image description here

but when I refresh token

const tokenRequest = {
  scopes: scopes,
  account: msalInstance.getActiveAccount(),
  forceRefresh: true,
} as SilentRequest;
console.log(await msalInstance.acquireTokenSilent(tokenRequest));

I dont see comUsername, wcfToken, organizationCode and personId enter image description here

Why am I not receiving the expected claims? I heard something about persisted claims, but I'm not sure where exactly I have to write that code. Here is my Azure custom policy.

<ClaimsProviders>
        <ClaimsProvider>
            <DisplayName>Local Account</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="SelfAsserted-RestAPISignin-Email">
                    <DisplayName>Local Account Signin</DisplayName>
                    <Protocol Name="Proprietary"
                        Handler="Web.TPEngine.Providers.SelfAssertedAttributeProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <Metadata>
                        <!--Sample:
                        disable the sign-up -->
                        <Item Key="setting.showSignupLink">false</Item>

                        <Item Key="SignUpTarget">SignUpWithLogonEmailExchange</Item>
                        <Item Key="setting.operatingMode">Email</Item>
                        <Item Key="ContentDefinitionReferenceId">api.selfasserted</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="signInName" />
                    </InputClaims>
                    <PersistedClaims>
                        <PersistedClaim ClaimTypeReferenceId="comUsername" />
                        <PersistedClaim ClaimTypeReferenceId="wcfToken" />
                        <PersistedClaim ClaimTypeReferenceId="personId" />
                        <PersistedClaim ClaimTypeReferenceId="organizationCode" />
                    </PersistedClaims>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="signInName" Required="true" />
                        <OutputClaim ClaimTypeReferenceId="password" Required="true" />
                        <OutputClaim ClaimTypeReferenceId="comUsername" />
                        <OutputClaim ClaimTypeReferenceId="wcfToken" />
                        <OutputClaim ClaimTypeReferenceId="personId" />
                        <OutputClaim ClaimTypeReferenceId="organizationCode" />
                        <OutputClaim ClaimTypeReferenceId="authenticationSource"
                            DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
                        <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="rest-api"
                            AlwaysUseDefaultValue="true" />
                    </OutputClaims>
                    <OutputClaimsTransformations>
                        <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
                        <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
                        <OutputClaimsTransformation
                            ReferenceId="CreateAlternativeSecurityId-With-SignInName" />
                    </OutputClaimsTransformations>
                    <ValidationTechnicalProfiles>
                        <ValidationTechnicalProfile ReferenceId="REST-Login" />
                    </ValidationTechnicalProfiles>
                    <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
        <ClaimsProvider>
            <DisplayName>Custom REST API</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="REST-Login">
                    <DisplayName>Validate user input data and return loyaltyNumber claim</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-rest-api-url-here</Item>
                        <Item Key="AuthenticationType">None</Item>
                        <Item Key="AllowInsecureAuthInProduction">true</Item>
                        <Item Key="SendClaimsIn">Body</Item>
                        <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
                        <Item Key="DebugMode">true</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="username" />
                        <InputClaim ClaimTypeReferenceId="password" />
                        <InputClaim ClaimTypeReferenceId="organizationCode"
                            DefaultValue="{OAUTH-KV:organizationCode}" AlwaysUseDefaultValue="true" />
                    </InputClaims>
                    <PersistedClaims>
                        <PersistedClaim ClaimTypeReferenceId="comUsername" />
                        <PersistedClaim ClaimTypeReferenceId="wcfToken" />
                        <PersistedClaim ClaimTypeReferenceId="personId" />
                        <PersistedClaim ClaimTypeReferenceId="organizationCode" />
                    </PersistedClaims>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="displayName" />
                        <OutputClaim ClaimTypeReferenceId="givenName" />
                        <OutputClaim ClaimTypeReferenceId="surName" />
                        <OutputClaim ClaimTypeReferenceId="comUsername" />
                        <OutputClaim ClaimTypeReferenceId="wcfToken" />
                        <OutputClaim ClaimTypeReferenceId="personId" />
                        <OutputClaim ClaimTypeReferenceId="organizationCode" />
                    </OutputClaims>
                    <UseTechnicalProfileForSessionManagement ReferenceId="SM-AAD" />
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>

        <ClaimsProvider>
            <DisplayName>Session Management</DisplayName>
            <TechnicalProfiles>

                <TechnicalProfile Id="SM-AAD">
                    <DisplayName>Session Mananagement Provider</DisplayName>
                    <Protocol Name="Proprietary"
                        Handler="Web.TPEngine.SSO.DefaultSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <PersistedClaims>
                        <PersistedClaim ClaimTypeReferenceId="objectId" />
                        <PersistedClaim ClaimTypeReferenceId="signInName" />
                        <PersistedClaim ClaimTypeReferenceId="authenticationSource" />
                        <PersistedClaim ClaimTypeReferenceId="identityProvider" />
                        <PersistedClaim ClaimTypeReferenceId="newUser" />
                        <PersistedClaim ClaimTypeReferenceId="executed-SelfAsserted-Input" />
                        <PersistedClaim ClaimTypeReferenceId="comUsername" />
                        <PersistedClaim ClaimTypeReferenceId="wcfToken" />
                        <PersistedClaim ClaimTypeReferenceId="personId" />
                        <PersistedClaim ClaimTypeReferenceId="organizationCode" />
                    </PersistedClaims>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="objectIdFromSession" DefaultValue="true" />
                        <OutputClaim ClaimTypeReferenceId="comUsername" />
                        <OutputClaim ClaimTypeReferenceId="wcfToken" />
                        <OutputClaim ClaimTypeReferenceId="personId" />
                        <OutputClaim ClaimTypeReferenceId="organizationCode" />
                    </OutputClaims>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    </ClaimsProviders>

    <UserJourneys>
        <UserJourney Id="SignUpOrSignInWithRestApiIDP">
            <OrchestrationSteps>

                <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp"
                    ContentDefinitionReferenceId="api.signuporsignin">
                    <ClaimsProviderSelections>
                        <ClaimsProviderSelection
                            ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
                    </ClaimsProviderSelections>
                    <ClaimsExchanges>
                        <!--Sample:
                        show the sign-in page with the REST API IDP-->
                        <ClaimsExchange Id="LocalAccountSigninEmailExchange"
                            TechnicalProfileReferenceId="SelfAsserted-RestAPISignin-Email" />
                    </ClaimsExchanges>
                </OrchestrationStep>

                <!-- Check if the user has selected to sign in using one of the social providers -->
                <OrchestrationStep Order="2" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                            <Value>objectId</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                        <!--Sample:
                        if user sign-in with the rest API, skip this orchestration step-->
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>socialIdpAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="FacebookExchange"
                            TechnicalProfileReferenceId="Facebook-OAUTH" />
                        <!-- Sample: Disable the sign-up
              <ClaimsExchange Id="SignUpWithLogonEmailExchange"
                        TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail"/> -->
                    </ClaimsExchanges>
                </OrchestrationStep>

                <!-- For social IDP authentication, attempt to find the user account in the
                directory. -->
                <OrchestrationStep Order="3" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>localAccountAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserReadUsingAlternativeSecurityId"
                            TechnicalProfileReferenceId="AAD-UserReadUsingAlternativeSecurityId-NoError" />
                    </ClaimsExchanges>
                </OrchestrationStep>

                <OrchestrationStep Order="4" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimEquals" ExecuteActionsIf="true">
                            <Value>authenticationSource</Value>
                            <Value>socialIdpAuthentication</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserReadWithObjectId"
                            TechnicalProfileReferenceId="AAD-UserReadUsingObjectId" />
                    </ClaimsExchanges>
                </OrchestrationStep>
                <OrchestrationStep Order="5" Type="ClaimsExchange">
                    <Preconditions>
                        <Precondition Type="ClaimsExist" ExecuteActionsIf="true">
                            <Value>objectId</Value>
                            <Action>SkipThisOrchestrationStep</Action>
                        </Precondition>
                    </Preconditions>
                    <ClaimsExchanges>
                        <ClaimsExchange Id="AADUserWrite"
                            TechnicalProfileReferenceId="AAD-UserWriteUsingAlternativeSecurityId" />
                    </ClaimsExchanges>
                </OrchestrationStep>

                <OrchestrationStep Order="6" Type="SendClaims"
                    CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />

            </OrchestrationSteps>
            <ClientDefinition ReferenceId="DefaultWeb" />
        </UserJourney>
    </UserJourneys>
    <RelyingParty>
        <DefaultUserJourney ReferenceId="SignUpOrSignInWithRestApiIDP" />
        <Endpoints>
            <!--points
            to refresh token journey when app makes refresh token request-->
            <Endpoint Id="Token" UserJourneyReferenceId="RedeemRefreshToken" />
        </Endpoints>
        <UserJourneyBehaviors>
            <JourneyInsights TelemetryEngine="ApplicationInsights"
                InstrumentationKey="9a643ead-c965-411f-8565-4db695a2e680" DeveloperMode="true"
                ClientEnabled="false" ServerEnabled="true" TelemetryVersion="1.0.0" />
            <ScriptExecution>Allow</ScriptExecution>
        </UserJourneyBehaviors>
        <TechnicalProfile Id="PolicyProfile">
            <DisplayName>PolicyProfile</DisplayName>
            <Protocol Name="OpenIdConnect" />
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="displayName" />
                <OutputClaim ClaimTypeReferenceId="givenName" />
                <OutputClaim ClaimTypeReferenceId="surname" />
                <OutputClaim ClaimTypeReferenceId="email" />
                <OutputClaim ClaimTypeReferenceId="comUsername" />
                <OutputClaim ClaimTypeReferenceId="wcfToken" />
                <OutputClaim ClaimTypeReferenceId="personId" />
                <OutputClaim ClaimTypeReferenceId="organizationCode" />
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
                <OutputClaim ClaimTypeReferenceId="identityProvider" />
                <OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true"
                    DefaultValue="{Policy:TenantObjectId}" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>

1 Answer 1

0

I can only assume that the refresh token user journey is not set up in full.

Sample - https://github.com/azure-ad-b2c/samples/tree/master/policies/refresh-token-journey

Some more information - https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/blob/main/README.md

Not the answer you're looking for? Browse other questions tagged or ask your own question.