I want to have 2 login providers for my app. Customers would connect with B2C and employees would connect with our AAD by SSO. Currently the B2C login for customers works with a SignIn V2 user flow, and our SSO works just fine for any other applications.
I followed these 2 pages to get started, using the exact same names:
- https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-get-started-custom
- https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-setup-aad-custom
They could be clearer but I think I got everything right as far as the XML goes. When I run my custom policy, I get a page with a login form and a button to connect with the AD. If I click the button, I'm redirected to the SSO page and I log in with my
user. The first time I'm asked to accept the permissions. So far so good, but after that I get redirected to https://mytenant.b2clogin.com/mytenant.onmicrosoft.com/oauth2/authresp, which gives a generic error 500 page. In the B2C Audit log, I see an event"Federate with an identity provider" with "Status: success" for the same datetime as my login so I believe the login works. Similarly, I can see a successful sign-in in the user's page in the AAD.
Is there something more I need to do that the MSDN pages missed? I should be getting redirected to jwt.ms with a token.
Relevant xml files (redacted):
TrustFrameworkBase.xml (only the parts I've modified):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><TrustFrameworkPolicy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
PolicySchemaVersion="0.3.0.0"
TenantId="mytenant.onmicrosoft.com"
PolicyId="B2C_1A_TrustFrameworkBase"
PublicPolicyUri="http://mytenant.onmicrosoft.com/B2C_1A_TrustFrameworkBase"><!-- snip default building blocks --><ClaimsProviders><ClaimsProvider><DisplayName>Local Account SignIn</DisplayName><TechnicalProfiles><TechnicalProfile Id="login-NonInteractive"><DisplayName>Local Account SignIn</DisplayName><Protocol Name="OpenIdConnect" /><Metadata><Item Key="UserMessageIfClaimsPrincipalDoesNotExist">We can't seem to find your account</Item><Item Key="UserMessageIfInvalidPassword">Your password is incorrect</Item><Item Key="UserMessageIfOldPasswordUsed">Looks like you used an old password</Item><Item Key="ProviderName">https://sts.windows.net/mytenantguid/</Item><Item Key="METADATA">https://login.microsoftonline.com/mytenant.onmicrosoft.com/.well-known/openid-configuration</Item><Item Key="authorization_endpoint">https://login.microsoftonline.com/mytenant.onmicrosoft.com/oauth2/token</Item><Item Key="response_types">id_token</Item><Item Key="response_mode">query</Item><Item Key="scope">email openid</Item><!-- Policy Engine Clients --><Item Key="UsePolicyInRedirectUri">false</Item><Item Key="HttpBinding">POST</Item></Metadata><InputClaims><InputClaim ClaimTypeReferenceId="signInName" PartnerClaimType="username" Required="true" /><InputClaim ClaimTypeReferenceId="password" Required="true" /><InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="password" /><InputClaim ClaimTypeReferenceId="scope" DefaultValue="openid" /><InputClaim ClaimTypeReferenceId="nca" PartnerClaimType="nca" DefaultValue="1" /></InputClaims><OutputClaims><OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="oid" /><OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid" /><OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" /><OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" /><OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" /><OutputClaim ClaimTypeReferenceId="userPrincipalName" PartnerClaimType="upn" /><OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="localAccountAuthentication" /></OutputClaims></TechnicalProfile></TechnicalProfiles></ClaimsProvider><!-- snip other default claim providers--><!-- snip default user journeys--> </TrustFrameworkPolicy>
TrustFrameworkExtension.xml
<?xml version="1.0" encoding="utf-8" ?><TrustFrameworkPolicy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
PolicySchemaVersion="0.3.0.0"
TenantId="mytenant.onmicrosoft.com"
PolicyId="B2C_1A_TrustFrameworkExtensions"
PublicPolicyUri="http://mytenant.onmicrosoft.com/B2C_1A_TrustFrameworkExtensions"><BasePolicy><TenantId>mytenant.onmicrosoft.com</TenantId><PolicyId>B2C_1A_TrustFrameworkBase</PolicyId></BasePolicy><BuildingBlocks></BuildingBlocks><ClaimsProviders><ClaimsProvider><DisplayName>Local Account SignIn</DisplayName><TechnicalProfiles><TechnicalProfile Id="login-NonInteractive"><Metadata><Item Key="client_id">ProxyIdentityExperienceFramework_AppId</Item><Item Key="IdTokenAudience">IdentityExperienceFramework_AppId</Item></Metadata><InputClaims><InputClaim ClaimTypeReferenceId="client_id" DefaultValue="ProxyIdentityExperienceFramework_AppId" /><InputClaim ClaimTypeReferenceId="resource_id" PartnerClaimType="resource" DefaultValue="IdentityExperienceFramework_AppId" /></InputClaims></TechnicalProfile></TechnicalProfiles></ClaimsProvider><ClaimsProvider><Domain>Mycompany</Domain><DisplayName>Login using Mycompany</DisplayName><TechnicalProfiles><TechnicalProfile Id="MycompanyProfile"><DisplayName>Mycompany Employee</DisplayName><Description>Login with your Mycompany account</Description><Protocol Name="OpenIdConnect"/><OutputTokenFormat>JWT</OutputTokenFormat><Metadata><Item Key="METADATA">https://login.windows.net/mytenant.onmicrosoft.com/.well-known/openid-configuration</Item><Item Key="ProviderName">https://sts.windows.net/mytenantguid/</Item><Item Key="client_id">AzureADB2CApp_AppdId</Item><Item Key="IdTokenAudience">AzureADB2CApp_AppdId</Item><Item Key="UsePolicyInRedirectUri">false</Item><Item Key="response_types">code</Item><Item Key="scope">openid</Item><Item Key="response_mode">form_post</Item><Item Key="HttpBinding">POST</Item></Metadata><CryptographicKeys><Key Id="client_secret" StorageReferenceId="B2C_1A_MycompanySecret"/></CryptographicKeys><OutputClaims><OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="oid"/><OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/><OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" /><OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" /><OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" /></OutputClaims><OutputClaimsTransformations><OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName"/><OutputClaimsTransformation ReferenceId="CreateUserPrincipalName"/></OutputClaimsTransformations></TechnicalProfile></TechnicalProfiles></ClaimsProvider></ClaimsProviders><UserJourneys><UserJourney Id="SignUpOrSignInMycompany"><OrchestrationSteps><OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signinwithpassword"><ClaimsProviderSelections><ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" /><ClaimsProviderSelection TargetClaimsExchangeId="MycompanyExchange" /></ClaimsProviderSelections><ClaimsExchanges><ClaimsExchange Id="LocalAccountSigninEmailExchange" TechnicalProfileReferenceId="SelfAsserted-LocalAccountSignin-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></Preconditions><ClaimsExchanges><ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" /><ClaimsExchange Id="MycompanyExchange" TechnicalProfileReferenceId="MycompanyProfile" /></ClaimsExchanges></OrchestrationStep><!-- Show self-asserted page only if the directory does not have the user account already (i.e. we do not have an objectId).
This can only happen when authentication happened using a social IDP. If local account was created or authentication done
using ESTS in step 2, then an user account must exist in the directory by this time. --><OrchestrationStep Order="3" Type="ClaimsExchange"><Preconditions><Precondition Type="ClaimsExist" ExecuteActionsIf="true"><Value>objectId</Value><Action>SkipThisOrchestrationStep</Action></Precondition></Preconditions><ClaimsExchanges><ClaimsExchange Id="SelfAsserted-Social" TechnicalProfileReferenceId="SelfAsserted-Social" /></ClaimsExchanges></OrchestrationStep><!-- This step reads any user attributes that we may not have received when authenticating using ESTS so they can be sent
in the token. --><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="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" /></OrchestrationSteps><ClientDefinition ReferenceId="DefaultWeb" /></UserJourney></UserJourneys></TrustFrameworkPolicy>
SignUpOrSigninMycompany.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><TrustFrameworkPolicy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
PolicySchemaVersion="0.3.0.0"
TenantId="mytenant.onmicrosoft.com"
PolicyId="B2C_1A_signup_signin_mycompany"
PublicPolicyUri="http://mytenant.onmicrosoft.com/B2C_1A_signup_signin_mycompany"><BasePolicy><TenantId>mytenant.onmicrosoft.com</TenantId><PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId></BasePolicy><RelyingParty><DefaultUserJourney ReferenceId="SignUpOrSignInMycompany" /><TechnicalProfile Id="PolicyProfile"><DisplayName>PolicyProfile</DisplayName><Protocol Name="OpenIdConnect" /><OutputClaims><OutputClaim ClaimTypeReferenceId="displayName" /><OutputClaim ClaimTypeReferenceId="givenName" /><OutputClaim ClaimTypeReferenceId="surname" /><OutputClaim ClaimTypeReferenceId="email" /><OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/><OutputClaim ClaimTypeReferenceId="tenantId" AlwaysUseDefaultValue="true" DefaultValue="{Policy:TenantObjectId}" /></OutputClaims><SubjectNamingInfo ClaimType="sub" /></TechnicalProfile></RelyingParty></TrustFrameworkPolicy>
In the Identity Experience Framework panel, I run B2C_1A_signup_signin_mycompany and choose testapp1 with https://jwt.ms as the repyl url.