The client specified not to prompt, but the client app requires re-authentication or MFA

I have MFA factor enrollment set org-wide to enroll users in MFA only when they are first challenged. Then I have an OIDC app using the Authorization Code flow which has a sign on policy that prompts for MFA once per session. So upon logging in to the OIDC app (making the call to /authorize), an MFA challenge is required.

Now my OIDC application using a separate, self-hosted okta signin widget for authentication. This means the OIDC app will redirect the user to a separate website that contains the signin widget. The signin widget then redirects back to the OIDC app once a session is established.

The issue I’m having is this:

  • Starting on the OIDC app, I click Login. This makes the /authorize call, which returns an error to my callback endpoint. The error is ‘login_required’, ‘The client specified not to prompt, but the user isn’t signed in.’. This is expected. I then redirect the user to the Okta signin widget website.
  • On the signin widget, they enter email and password, and are redirected back to the OIDC app.
  • The OIDC app tries to make the /authorize call again, and another error is returned to my callback endpoint. This error is ‘login_required’, ‘The client specified not to prompt, but the client app requires re-authentication or MFA.’.
  • So now I need to somehow redirect back to the signin widget website but manually initiate MFA enrollment. Is this possible?

Hi @cat,
Does this error occur even if there is no prompt parameter in /authorize request ?

No, but then the Okta-hosted signin widget would be shown instead of my self-hosted widget.

Hi @cat

The self hosted Okta sign-in widget does not support the application level MFA. The solution would be to either redirect the users to the Okta /authorize endpoint or use organization level MFA under Admin >> Security >> Authentication >> Sign On (if you are using the developer console administrative interface, you will need to switch to Classic UI by hovering over Developer Console on top left corner).

Ok bummer! Do you know if support for app-level MFA is on the roadmap for the signin widget?

This feature is also known as ‘step-up’ authentication for OAuth/OIDC. Requests for this capability have been made since at least 2017. This capability exists for applications using SAML (which confuses people – why does it exist for SAML, but not for OAuth??).
Over a year ago, I did an analysis of the APIs and process flow used by the Okta Widget in the 2.3 release and saw that there was no way for the Okta widget to retrieve the list of 2nd factors associated with a user after the user has completed primary authentication. This is a HUGE gap in functionality – and shows that Okta seems to be deaf to existing customers’ enhancement requests, as more than one customer has requested this functionality.

Thanks for the info! I agree, this is really frustrating. Why is application level MFA even a feature if you can’t use it for OIDC apps??

@dragos It seems like the Okta-hosted signin widget supports App level MFA. Is it using some proprietary Okta APIs to do this? Or can you share the implementation logic so I can replicate it? I’m very comfortable modifying the widget source code itself - we’ve already done this extensively to add other missing features.

Hi @cat

When accessing the authorization endpoint and having the app level MFA prompt, there is a stateToken generated which is used to prompt for MFA.

If you are using a custom domain, you can update the login page for the custom domain URL and capture the stateToken as follows:

var config = OktaUtil.getSignInWidgetConfig();
if (config.stateToken) 
	window.location.href= 'https://your.app.com/widget.html?token=' + config.stateToken;

Once Okta redirects to widget.html, you can grab the token from the query parameter and use it in the widget’s code as follows:

var oktaSignIn = new OktaSignIn({
    baseUrl: "https://custom.domain.com",
    stateToken: 'token-from-query-param'
    ....
});

This will allow your users to be prompted for MFA on your website successfully.

(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)

Hi @dragos,

Thank you for the suggestion. I implemented this and got it to work! The Okta-hosted widget is redirecting to my self-hosted widget, and I’m able to retrieve the stateToken to get the MFA prompt.

Just so others know, after MFA is successful, I’m getting a callback in function success(res) like this:

function success(res) {
    // res.status === 'SUCCESS'
    // res.type === 'SESSION_STEP_UP'
    // res.session === undefined
    // res.stepUp === {
    //    finish: function(),
    //    url: 'https://{oktaBaseUrl}/login/step-up/redirect?stateToken={stateToken}'
    // }
}

At this point you can’t do res.session.setCookieAndRedirect() like you might normally. Instead, use res.stepUp.finish(). It looks like this function will do the setCookieAndRedirect() for you, and will bring you back to the redirect_uri on your original /authorize request.