I am trying to integrate a custom OIDC IDP in Azure AD B2C And then use React Native App Auth Library to authenticate users in my app
Here is the OIDC Technical Profile in TrustFrameExtensions
<ClaimsProvider>
<Domain>stgqpass.gov.qa</Domain>
<DisplayName>Login STG QPASS</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="STGQPASS-OpenIdConnect">
<DisplayName>STG QPASS</DisplayName>
<Description>Login with your QPASS account</Description>
<Protocol Name="OpenIdConnect" />
<Metadata>
<Item Key="METADATA">/.well-known/openid-configuration</Item>
<Item Key="client_id">our-clientid-from-idp</Item>
<Item Key="response_types">code</Item>
<Item Key="scope">openid profile</Item>
<Item Key="response_mode">query</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">false</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_QPASSTEST" />
</CryptographicKeys>
<!-- STGQpass has userId in token , so we are mapping it to issuerUserId-->
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="userId" />
<!-- We need to map the claims defined in policy(LHS) to the name defined in IDP(RHS)-->
<!-- STGQPass firstNameEn maps to givenName in B2C-->
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstNameEn" />
<OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="lastNameEn" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
<OutputClaim ClaimTypeReferenceId="mobile" PartnerClaimType="mobileNumber" />
<OutputClaim ClaimTypeReferenceId="telephoneNumber" PartnerClaimType="UserQid" />
<OutputClaim ClaimTypeReferenceId="postalCode" PartnerClaimType="UserQid" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
<OutputClaim ClaimTypeReferenceId="identityProvider" PartnerClaimType="iss" />
<!-- AD B2C's objectId is based on stqpass sub -->
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
<!-- <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" /> -->
<!-- <OutputClaim ClaimTypeReferenceId="identityProviderAccessToken" PartnerClaimType="{oauth2:access_token}" /> -->
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
<OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
<OutputClaimsTransformation ReferenceId="CreateDisplayNameFromFirstNameAndLastName" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
Here is the discovery url of the IDP /.well-known/openid-configuration
Here is the RP file :
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUpOrSignIn" />
<Endpoints>
<!--points to refresh token journey when app makes refresh token request-->
<Endpoint Id="Token" UserJourneyReferenceId="RedeemRefreshToken" />
</Endpoints>
<UserJourneyBehaviors>
<JourneyInsights TelemetryEngine="ApplicationInsights" InstrumentationKey="3ae2-2e91-abcd-1234-e94efcd8" DeveloperMode="true" ClientEnabled="false" ServerEnabled="true" TelemetryVersion="1.0.0" />
</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="mobile" />
<!-- objectId of B2C is displayed as sub in JWT token-->
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" />
<OutputClaim ClaimTypeReferenceId="identityProvider" />
<OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" />
<!--<OutputClaim ClaimTypeReferenceId="identityProviderAccessToken" PartnerClaimType="idp_access_token" /> -->
<OutputClaim ClaimTypeReferenceId="CorrelationId" DefaultValue="{Context:CorrelationId}" />
<!--OutputClaim ClaimTypeReferenceId="extension_UserQid" /-->
<OutputClaim ClaimTypeReferenceId="postalCode" />
<OutputClaim ClaimTypeReferenceId="telephoneNumber" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
The re-direct urls registered with the IDP are as follows:
.onmicrosoft/oauth2/authresp
Here is the sample ID token received from the IDP by manually calling the endpoints in Postman
```
{
"kid": "ygrhhxvlqglihcpy",
"alg": "ES256"
}.{
"iss": ";,
"sub": "abcdf667-abcd-1234-efgh-5cef3d90d123",
"aud": "our-clientid-from-idp",
"exp": 1742720579,
"iat": 1742719379,
"auth_time": 1742719273,
"acr": "AAL/1",
"amr": [
"digital-document"
],
"sid": "abce3d89-abcd-1234-efgh-9b507b783123",
"UserQid": "11111111111",
"accountSubType": "resident",
"accountType": "qid",
"birthdate": "1965-06-14",
"cardDocumentType": "resident_permit",
"cardExpiryDate": "2026-09-04",
"documentExpiryDate": "2026-09-04",
"documentIssuingCountry": "QA",
"documentNumber": "11111111111",
"documentType": "resident_permit",
"email": "[email protected]",
"emailVerified": true,
"firstNameAr": "ل\"",
"firstNameEn": "JOHN",
"ial": 0,
"lastNameAr": "ِ",
"lastNameEn": "DOE",
"middleNameAr": "و : .\" َ ل ١ ",
"middleNameEn": "VAN",
"mobileNumber": "+97411111111",
"nationality": "IND",
"passportExpiryDate": "2036-05-17",
"passportNumber": "N9876523",
"phoneNumberVerified": true,
"userId": "1234b006-abcd-1234-efgh-655d14671234",
"username": "11111111111"
}.[Signature]
```
Here is the config used in React Native App
//Tried all the following in issuer
//
xxx994cffxxx/b2c_1a_qpass_stg_signup_signin/v2.0/
//
xxx994cffxxx/b2c_1a_qpass_stg_signup_signin/v2.0/
``` //.onmicrosoft/b2c_1a_qpass_stg_signup_signin/v2.0/
```
``` //.onmicrosoft/b2c_1a_qpass_stg_signup_signin/v2.0/
```
const config = {
issuer:
```'.onmicrosoft/b2c_1a_qpass_stg_signup_signin/v2.0/',```
clientId: '12339044-abcd-1234-8f2d-bc2605315fff',
redirectUrl: 'com.b2cqpass://home/',
scopes: ['openid', 'profile'],
iosPrefersEphemeralSession: true,
};
The config in React Native was done based on
When I try to login, the app redirects to B2C, B2C redirects to IDP , authentication is successfull on the IDP page , but we get the below error in our app when re-directed back to our app
net.openid.appauth.AuthorizationException: AADB2C90289: We encountered an error connecting to the identity provider. Please try again later.
Correlation ID: 9aabe384-77c6-4fe6-8943-8d0f22d827bd
Timestamp: 2025-03-27 08:25:29Z
Any pointers on the root cause will be very helpful.
Here are the details from Azure App Insights
[
{
"Kind": "Headers",
"Content": {
"UserJourneyRecorderEndpoint": "urn:journeyrecorder:applicationinsights",
"CorrelationId": "b48e7631-c19c-4ead-8792-56822c4e77f7",
"EventInstance": "Event:ClaimsExchange",
"TenantId": "ourtenant.onmicrosoft",
"PolicyId": "B2C_1A_QPASS_STG_signup_signin"
}
},
{
"Kind": "Transition",
"Content": {
"EventName": "ClaimsExchange",
"StateName": "Initial"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.ClaimsExchangeMessageValidationHandler"
},
{
"Kind": "Transition",
"Content": {
"EventName": "ClaimsExchange",
"StateName": "Microsoft.Cpim.Protocols.PartnerProtocolException"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.IsPartnerErrorReachesMaximumRetriesHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"Statebag": {
"MACHSTATE": {
"c": "2025-03-27T09:16:11.6908736Z",
"k": "MACHSTATE",
"v": "Microsoft.Cpim.Protocols.PartnerProtocolException",
"p": true
},
"JC": {
"c": "2025-03-27T09:16:08.4140057Z",
"k": "JC",
"v": "en",
"p": true
},
"ORCH_CS": {
"c": "2025-03-27T09:16:08.4510066Z",
"k": "ORCH_CS",
"v": "2",
"p": true
},
"ORCH_IDX": {
"c": "2025-03-27T09:16:08.4520075Z",
"k": "ORCH_IDX",
"v": "0",
"p": true
},
"RA": {
"c": "2025-03-27T09:16:08.4520075Z",
"k": "RA",
"v": "0",
"p": true
},
"RPP": {
"c": "2025-03-27T09:16:08.4120051Z",
"k": "RPP",
"v": "OAUTH2",
"p": true
},
"RPIPP": {
"c": "2025-03-27T09:16:08.4120051Z",
"k": "RPIPP",
"v": "OAuth2ProtocolProvider",
"p": true
},
"OTID": {
"c": "2025-03-27T09:16:08.4130058Z",
"k": "OTID",
"v": "1230b4cf-abcd-1234-ade2-471994cffdef",
"p": true
},
"APPMV": {
"c": "2025-03-27T09:16:08.4140057Z",
"k": "APPMV",
"v": "V2",
"p": true
},
"CC": {
"c": "2025-03-27T09:16:08.4410053Z",
"k": "CC",
"v": "AWPzMhoPc5V1GIabcdefghdqtfKtIH0w29RmojiY",
"p": true
},
"CCM": {
"c": "2025-03-27T09:16:08.4410053Z",
"k": "CCM",
"v": "S256",
"p": true
},
"IC": {
"c": "2025-03-27T09:16:08.4430058Z",
"k": "IC",
"v": "False",
"p": true
},
"MSG(691deb19-a4b7-4c03-b0ab-e41afbe5c03b)": {
"c": "2025-03-27T09:16:08.4450062Z",
"k": "MSG(691deb19-a4b7-4c03-b0ab-e41afbe5c03b)",
"v": "{\"TenantId\":\"ourtenant.onmicrosoft\",\"PolicyId\":\"B2C_1A_QPASS_STG_signup_signin\",\"RedirectUri\":\"com.b2cbiometricauth://home/\",\"AdditionalParameters\":{\"code_challenge\":\"AWPzMhoPc5V1GIbacdjSH0dqtfKtIH0w29RmojiY\",\"code_challenge_method\":\"S256\"},\"Nonce\":\"HECvOlY9Qa6UmiSRnREgxA\",\"State\":\"ZZrS-z8DskvoaSNT5Hp3cQ\",\"ClientId\":\"abc39044-abcd-1234-efgh-bc2605315def\",\"ResponseType\":\"code\",\"ResponseRedirector\":{\"URI\":\"com.b2cbiometricauth://home/\",\"D\":false,\"WF\":true,\"R\":false,\"S\":false},\"Scope\":\"openid profile\",\"AppModelVersion\":1,\"ScopedProviders\":[]}",
"p": true,
"t": "OAuth2"
},
"IMESSAGE": {
"c": "2025-03-27T09:16:08.4450062Z",
"k": "IMESSAGE",
"v": "691deb19-a4b7-4c03-b0ab-e41afbe5c03b",
"p": true
},
"TAGE": {
"c": "2025-03-27T09:16:11.3845665Z",
"k": "TAGE",
"v": "StgQPASSExchange",
"p": true
},
"SE": {
"c": "2025-03-27T09:16:09.1214254Z",
"k": "SE",
"v": "Social",
"p": true
},
"CMESSAGE": {
"c": "2025-03-27T09:16:10.4435926Z",
"k": "CMESSAGE",
"v": "691deb19-a4b7-4c03-b0ab-e41afbe5c03b",
"p": true
},
"ComplexItems": "_MachineEventQ, REPRM, TCTX, M_EXCP"
},
"PredicateResult": "False"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.IsPartnerReauthenticateActionHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"PredicateResult": "False"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.IsPartnerClientInvalidActionHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"PredicateResult": "False"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.NoOpHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"PredicateResult": "True"
}
},
{
"Kind": "Action",
"Content": "Web.TPEngine.SSO.SSOSessionEndHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true
}
},
{
"Kind": "Action",
"Content": "Web.TPEngine.StateMachineHandlers.SendErrorHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"RecorderRecord": {
"Values": [
{
"Key": "SendErrorTechnicalProfile",
"Value": "OpenIdConnectProtocolProvider"
},
{
"Key": "Exception",
"Value": {
"Kind": "Handled",
"HResult": "80131500",
"Message": "We encountered an error connecting to the identity provider. Please try again later.",
"Data": {
"IsPolicySpecificError": false
}
}
}
]
},
"Statebag": {
"SE": {
"c": "2025-03-27T09:16:11.7048739Z",
"k": "SE",
"v": "",
"p": true
}
}
}
},
{
"Kind": "Action",
"Content": "Web.TPEngine.StateMachineHandlers.TransactionEndHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true
}
}
]