Update user metadata after MFA completion

Hello,

I’m working on a custom Action to provide step-up MFA when a user logs in from a new device. This works by passing in the deviceId as a query parameter and when it doesnt match the deviceId in the user metadata, (or first time login) they are pushed into the MFA flow. Upon completion, their metadata is updated and can log in from the known devices stored in their user profile.

The issue I’m having is verifying that they completed MFA before the metadata updated. I’m trying to reference the event.authentication.methods object for this but the Action is executed before event.authentication can be updated. Is there a way to verify MFA has been completed in the login flow before completing some task?

See example below:

exports.onExecutePostLogin = async (event, api) => {
//Pull request_id and visitor_id from query string
let device = event.request.query.device
var array = device.split(" ");
const vid = array[0]
const rid = array[1]
//confirm vid and rid values

let metadata = event.user.app_metadata
//Capture device info in Auth0 user profile
//If user does not have an existing device_id

if(!metadata.device_id){
api.multifactor.enable('any')
}

//force MFA on users logging in from new device

if (metadata.device_id && !event.user.app_metadata.device_id.includes(vid)) {
api.multifactor.enable('any');
}

//verify successful MFA before updating record
if (event.authentication?.methods.find(x => x.name == 'mfa')) {

//Update metadata if MFA is successful
if (!metadata.device_id) {
api.user.setAppMetadata("device_id", [vid]);
console.log('metadata updated')

} else if (!metadata.device_id.includes(vid)) {
let newArr = metadata.device_id;
newArr.unshift(vid)
api.user.setAppMetadata("device_id",newArr );
console.log('MFA triggered based on new device')
}
}

};

Hi there @hunter1!

Unfortunately as you’ve noticed MFA does not complete until after Actions/Rules have executed - It’s outside the scope of an Action, but you could potentially look at ID token claims to see if MFA was performed, or add a claim to an access token to indicate that MFA was required for a given login and go about it that way. An ID token returned after a login requiring MFA will contain both the acr and amr claims:

Hope this helps!

having the same need, thanks for the hints above.

Using rails + omniauth, request.env["omniauth.auth"] outputs the following :


 {"provider"=>"auth0",
"uid"=>"auth0|xxx",
"info"=>
 {"name"=>"auth0|xxx",
  "nickname"=>nil,
  "email"=>nil,
  "image"=>nil},
"credentials"=>
 {"token"=>
   "...",
  "expires_at"=>1679159975,
  "expires"=>true,
  "id_token"=>
   "...",
  "token_type"=>"Bearer",
  "refresh_token"=>nil},
"extra"=>
 {"raw_info"=>
   {"iss"=>"https://xxx-development.eu.auth0.com/",
    "aud"=>"q3-E7Xa6G7JgS8MLIAx_gry9VutMkBpN",
    "iat"=>1679073576,
    "exp"=>1679109576,
    "sub"=>"auth0|xxx",
    "auth_time"=>1679073575,
    "acr"=>"http://schemas.openid.net/pape/policies/2007/06/multi-factor",
    "amr"=>["mfa"],
    "sid"=>"xxx",
    "nonce"=>"xxx"}}}

( request.env["omniauth.auth"] will be available within your callback route)

As advertised in the previous comment, we can see acr / amr after an MFA authentification. There aren’t present after a standard auth via email/password

1 Like

Hey there @ben9! That’s great, thanks for the input :slight_smile: I wanted to also add that using log streams may also be an option.

Cheers!

Hi,

I’m looking for a similar behavior.

I’d like to update app_metadata with the phone number that he user to enroll or verify MFA.

I’m not sure how it’s possible with what you’ve proposed.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.