Skip to main content

Perhaps the Service Provider section of the R&D Forums is a better place to ask, but I figured I’d check here to see if anyone has an easy button for resetting MFA on an AD login specified by AD group for an Admin in the Service Provider Console. I reloaded my phone and the Duo app didn’t import my 3rd party MFA logins.  Fortunately, I have other admin logins I can use.

So far what I’ve gotten is that you have to apparently use the REST API (which seems silly to me if that’s the case, feature request coming up…..) because the user only exists in an AD group that was specified for access.  While I’m not great with API’s, the the Swagger UI should make things easier. 

That said, I haven’t yet figured out how to authenticate with Swagger using an account that has MFA enabled.  I might be able to get it once I get past that hump.  I was hoping that if I disabled the MFA requirements, I could log in and reset MFA from the user access, but it appears to prompt for MFA once enrolled even if the MFA requirement has been disabled.  I also tried specifying the AD user individually and removing the MFA requirement, but still prompted.

 

Enabling and Disabling MFA for Administrator Portal Users

Enabling and Disabling MFA using REST API

Evaluation with the Swagger UI:  Getting Authorization Tokens

I can’t answer this, but recently tried the MFA using the OTP generator in 1password for a login somewhere and man that thing is sweet.

Autofills the webpage - nice.

syncs between devices  - nice.

when my phone dies, gets lost or upgraded, just reinstall the app - nice.

 

 

 

 


I can’t answer this, but recently tried the MFA using the OTP generator in 1password for a login somewhere and man that thing is sweet.

Autofills the webpage - nice.

syncs between devices  - nice.

when my phone dies, gets lost or upgraded, just reinstall the app - nice.

 

As an MSP, when there is some sort of shared login, it’s kept in IT Glue’s virtual MFA.  Pretty slick.

For my own logins, I’ve been using Duo except I also use the Microsoft Authenticator which I’ve had to use in the past for some sites (Barracuda Cloud Control to start because it was unreliable at best with Duo), and the MS Authenticator does a better job of backing up and restoring 3rd party accounts.  I’m now transitioning my 3rd party accounts away from the Duo authenticator and only using it for the Duo managed accounts.  


To answer you question:

No, to my knowledge you cannot use the API with a MFA enabled account. (its not possible on VBR12 so i think it also applies to VSPC although its a totally separate authentication system.

I also did a reset for a admin user (on VSPC7) and that worked just fine.
Did you also create a Supportcase for this?


To answer you question:

No, to my knowledge you cannot use the API with a MFA enabled account. (its not possible on VBR12 so i think it also applies to VSPC although its a totally separate authentication system.

I also did a reset for a admin user (on VSPC7) and that worked just fine.
Did you also create a Supportcase for this?

I haven’t but will need to.  It’s been a lower priority item though.


Hi @dloseke 

Just wrote a bit of code for you (couldnt find the one I created before for the previous VSPC version.
Its untested but should work:

 

## variables
$server = '' #VSPC url
$port = '443'
$version = '3'
$AuthToken = '' #API token with read/write

## api calls
$headers=@{}
$headers.Add("Content-Type", "application/json; charset=utf-8")
$headers.Add("Accept", "application/json")
$headers.Add("Authorization", "Bearer $($AuthToken)")


# first get all organizations
$page = 0
$objects = @()
$objects = do {
$endpoint = "organizations"
#request page
$request = Invoke-RestMethod -uri "https://$($server):$($port)/api/v$($version)/$($endpoint)?limit=100&offset=$page" -Method GET -headers $headers

#save results
$request.data

#go to next page
$page += $request.meta.pagingInfo.count

#wait (429)
Start-Sleep -Milliseconds 1000

} while ($request.meta.pagingInfo.offset -ne $request.meta.pagingInfo.total)

$providerinstance = $objects | Where-Object {$_.type -eq "provider"}

# get all users
$page = 0
$objects = @()
$objects = do {
$endpoint = "users/logins"
#request page
$request = Invoke-RestMethod -uri "https://$($server):$($port)/api/v$($version)/$($endpoint)?limit=100&offset=$page" -Method GET -headers $headers

#save results
$request.data

#go to next page
$page += $request.meta.pagingInfo.count

#wait (429)
Start-Sleep -Milliseconds 1000

} while ($request.meta.pagingInfo.offset -ne $request.meta.pagingInfo.total)

# select users in provider company
$providerusers = $objects | ? {$_.companyid -eq $providerinstance.instanceUid}
$providerusers | ft -AutoSize

# disable MFA
$useruuid = "uuid" # set uuid from previous step

#create payload
$body = @(@PSCustomObject]@{
value = "replace"
path = 'mfaPolicyStatus'
op = 'disabled'
}
)
$json_body = convertto-json -InputObject $body

#send patch request to disable MFA for user
$request = Invoke-RestMethod -uri "https://$($server):$($port)/api/v$($version)/users/$($useruuid)" -Method PATCH -headers $headers -body

 


Hi @dloseke 

Just wrote a bit of code for you (couldnt find the one I created before for the previous VSPC version.
Its untested but should work:

 

## variables
$server = '' #VSPC url
$port = '443'
$version = '3'
$AuthToken = '' #API token with read/write

## api calls
$headers=@{}
$headers.Add("Content-Type", "application/json; charset=utf-8")
$headers.Add("Accept", "application/json")
$headers.Add("Authorization", "Bearer $($AuthToken)")


# first get all organizations
$page = 0
$objects = @()
$objects = do {
$endpoint = "organizations"
#request page
$request = Invoke-RestMethod -uri "https://$($server):$($port)/api/v$($version)/$($endpoint)?limit=100&offset=$page" -Method GET -headers $headers

#save results
$request.data

#go to next page
$page += $request.meta.pagingInfo.count

#wait (429)
Start-Sleep -Milliseconds 1000

} while ($request.meta.pagingInfo.offset -ne $request.meta.pagingInfo.total)

$providerinstance = $objects | Where-Object {$_.type -eq "provider"}

# get all users
$page = 0
$objects = @()
$objects = do {
$endpoint = "users/logins"
#request page
$request = Invoke-RestMethod -uri "https://$($server):$($port)/api/v$($version)/$($endpoint)?limit=100&offset=$page" -Method GET -headers $headers

#save results
$request.data

#go to next page
$page += $request.meta.pagingInfo.count

#wait (429)
Start-Sleep -Milliseconds 1000

} while ($request.meta.pagingInfo.offset -ne $request.meta.pagingInfo.total)

# select users in provider company
$providerusers = $objects | ? {$_.companyid -eq $providerinstance.instanceUid}
$providerusers | ft -AutoSize

# disable MFA
$useruuid = "uuid" # set uuid from previous step

#create payload
$body = @( PSCustomObject]@{
value = "replace"
path = 'mfaPolicyStatus'
op = 'disabled'
}
)
$json_body = convertto-json -InputObject $body

#send patch request to disable MFA for user
$request = Invoke-RestMethod -uri "https://$($server):$($port)/api/v$($version)/users/$($useruuid)" -Method PATCH -headers $headers -body

 

Thanks...I’ll check this out next chance I get!


Hi @dloseke ,

By accident I found the API reference for removing the MFA device that is attached to a user:

https://helpcenter.veeam.com/docs/vac/rest/mfa.html?ver=80

The link to the api reference doesn’t work but here is the correct one: https://helpcenter.veeam.com/docs/vac/rest/reference/vspc-rest.html?ver=80#tag/Accounts/operation/UpdateUserLogin


The fix for you should be: send a patch with the property "mfaPolicyStatus” on disabled.
So I think the script should work :-)

The datamodel for the payload for this endpoint:
 

instanceUid string($uuid)
readOnly: true

UID assigned to a user.

organizationUid string($uuid)
readOnly: true

UID assigned to a user organization.

userName string
readOnly: true

User name.

status string
default: Enabled
x-extensible-enum: true
x-ms-enum: OrderedMap { "name": "UserStatus" }

User status.

Enum:
n Unknown, Enabled, Disabled ]
mfaPolicyStatus string
default: Disabled
x-extensible-enum: true
x-ms-enum: OrderedMap { "name": "UserMfaPolicyStatus" }

Status of MFA configuration requirement for user.

Enum:
Array u 4 ]
mfaPolicyConfigurationStatus string
default: NotConfigured
readOnly: true
x-extensible-enum: true
x-ms-enum: OrderedMap { "name": "UserMfaPolicyConfigurationStatus" }

Status of user MFA policy configuration.

Enum:
o Unknown, NotConfigured, Configured ]
role* UserRolestring
x-extensible-enum: true
x-ms-enum: OrderedMap { "name": "UserRole" }

User role.

Enum:
Array . 16 ]
profile* {...}
credentials {...

Comment