2
votes

We have a custom Azure AD B2C Sign-in/Sign-up policy in place (SAML-based, the default policy doesn't do what we need).

We're able to customize the page UI as expected, via a content definition like:

<ContentDefinition Id="api.localaccountsignin">
  <LoadUri>https://example.com/SAMLSignIn.html</LoadUri>
  <RecoveryUri>~/common/default_page_error.html</RecoveryUri>
  <DataUri>urn:com:microsoft:aad:b2c:elements:selfasserted:1.1.0</DataUri>
  <Metadata>
    <Item Key="DisplayName">Local account sign in page</Item>
  </Metadata>
</ContentDefinition>

But attempting to customize the error page, via:

<ContentDefinition Id="api.error">
  <LoadUri>https://example.com/SAMLErrorPage.html</LoadUri>
  <RecoveryUri>~/common/default_page_error.html</RecoveryUri>
  <DataUri>urn:com:microsoft:aad:b2c:elements:globalexception:1.1.0</DataUri>
  <Metadata>    
    <Item Key="DisplayName">Error page</Item>
  </Metadata>
</ContentDefinition>

changes nothing. The SAMLSignIn.html page is still used (albeit with the contents of whatever signin error occurred). This happens whether we test with invalid user names, bad passwords, whatever.

Even setting

<Item Key="RaiseErrorIfClaimsPrincipalDoesNotExist">true</Item>

in the associated <ValidationTechnicalProfile> doesn't force the error.

The user journey as seen in ApplicationInsights shows only a Web.TPEngine.Providers.BadArgumentRetryNeededException; no other errors or exceptions are logged.

How can we cause a custom error page to be used on login failure (for whatever reason)?

The documentation, such as it is, seems to imply we're doing the right thing (as does How to Create a Custom Error Page in Azure AD B2C | Custom Policies). I can't find any suggestion that we need to specify custom error handling in the UserJourney, nor any means by which we could do so if we wanted.

1
hm, just played around with a similar case. I got my error page displayed, but because I identify my erroneous behavior in a claim. Then it is relatively easy. What happens when error occurs - you see blank page on B2C /authresp or you are redirected to your application with query string indicating the error? Generally it is much easier to handle errors in your application if you got to that point of being redirected. And why you use api.localacocuntsignin for SAML?! In which OrchestrationStep does the error occur? - astaykov
localaccountsignin is used since we don't want signups occurring via the SAML flow. The error that occurs (as expected) if, for example, I log in as an unknown user. We see the error just fine, but within the signin page's custom HTML, not the error page HTML. I believe this all happens within the CombinedSignInAndSignUp step; we're just using the localaccountsignin content definition. - Paul Roub
do you only have single claims provider registered for the journey - the SAML one? If so you will be just redirected to the SAML IdP login page. Next you will land on the B2C with the result of SAML login. If you enter bad password at your SAML IdP, you will see the error page of SAML IdP, not the error page of B2C. It seems like you trying to sign-in locally and not via your SAML provider. That's why you only see the custom sign-in page. I wonder what error you see in the sign-in page? Bad password? Then this is the local sign-in result, which is expected to be on that page. - astaykov
api.error seems to be used only for unhandled erros. Any IdP errors (like not consented) are handled in a way that user is redirected to your application with query string in form of error=server_error&error_description=AADB2C%3a+An+exception+has+occurred..... - astaykov
B2C is the SAML provider, that is, we're logging into a relying party using B2C for authentication. B2C takes over to show the login page. If all goes well, we end up back at the third-party site, logged in. Any failures are shown in the context of the SAML Journey's login page. - Paul Roub

1 Answers

2
votes

To summarize:

You are using local account sign-in with SAML issuer. This makes sign-in process happen on Azure AD B2C sign-in page. The error messages you see are just regular validation error messages. This all happens on the sign-in page, not the error page. Error content is only used by the engine when an unhandled exception breaks the execution of the user journey. Which is not the case with a regular sign-in.

Your option to customize validation errors are limited to using pure CSS on the sign-in page.

A really complex customization is demonstrated here

The document describing UI customization in general, is here

And UI customization using custom policy here

At your best effort you will come with some nice error messages like these:

enter image description here