FusionAuth
    • Home
    • Categories
    • Recent
    • Popular
    • Pricing
    • Contact us
    • Docs
    • Login

    Additional authentication assurance without using step-up MFA

    Scheduled Pinned Locked Moved Solved
    Q&A
    step-up mfa auth
    1
    2
    541
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • danD
      dan
      last edited by

      I need the user to prove they’re still the user before a sensitive action. Do I really have to wire up the Two-Factor APIs to use step-up MFA auth to do that?

      --
      FusionAuth - Identity Without Constraints
      https://fusionauth.io

      danD 1 Reply Last reply Reply Quote 0
      • danD
        dan @dan
        last edited by dan

        You can use the linked APIs, and that’s the option most people find first. The step-up flow in the API docs works, but means your app owns the challenge. It has to start it, collect the code, and handle the result. That’s a lot for what is basically “make the user log in again because they are about to do a sensitive thing.”

        There’s another way that’s a little different, and it leverages login. Since version 1.60 the authorize endpoint supports the standard OIDC prompt and max_age parameters.

        When your app hits a sensitive action, don't call any specific APIs. Instead, it can redirect the user to /oauth2/authorize with prompt=login and/or with a max_age small enough that their existing SSO session doesn’t satisfy it. FusionAuth shows the hosted login page, the user authenticates, and you get a fresh token back. Same code you already wrote for login, with one query parameter added.

        Make sure you put the current page/location in the state so you can deliver the customer back to where they were. Here's a video on deep linking.

        Using either max_age=0 and prompt=login end up in roughly the same place. I’d use max_age if you want a window like “re-auth if it’s been more than five minutes,” and prompt=login if you want it every time.

        A successful redirect doesn’t prove everything. Your app still has to decide whether the token it’s looking at came from a recent authentication.

        That’s what the auth_time claim is for. It’s a reserved claim in the JWT body (it moved there in 1.60, and lambdas can’t override it), so your resource server compares it against the clock and rejects beyond your threshold. If it’s too old, send the user back through authorize.

        That’s basically the max_age half of RFC 9470, just without FusionAuth issuing the WWW-Authenticate challenge for you. You’d write that 401 yourself.

        Caveats:.

        • This forces a re-login, not necessarily a stronger one. If the user re-authenticates with a password and nothing else, you’ve proven recency and nothing about strength. If you need the second factor on that re-auth, you need MFA to actually fire. A static policy of Required will do it. On Enterprise, the MFA Requirement Lambda can make the decision per request.
        • There’s no acr-style “this was step-up” claim. You get “authenticated at time T,” not “authenticated with a second factor at time T.” If your auditors need the latter, this approach won’t give it to you cleanly, and falling back to the step-up auth API is a better option.
        • It’s a full redirect. For a banking-style “confirm this transfer” flow where bouncing the user to another page is a non-starter, the step-up API approach is still right.
        • This only works when you are using the hosted login pages, not the Login API.

        The short version: if sensitive actions are coarse-grained (“view the billing page,” “change the email address”), the redirect approach might work for you. It’s less code, the hosted pages handle the UI, and you’re not maintaining a custom MFA challenge.

        But if you need per-operation binding or proof of which factor was used, look at the step-up API.

        --
        FusionAuth - Identity Without Constraints
        https://fusionauth.io

        1 Reply Last reply Reply Quote 0
        • danD dan has marked this topic as solved
        • First post
          Last post