UMFA APIs for Native iOS Applications
The Universal MFA (UMFA) module provides a flexible solution for handling multi-factor authentication processes. It leverages FIDO2 technology to enable secure credentials bound to the user's device.
Interface Definitions
Jump to: Swift, Objective-C
Getting the version number of the SDK library: UMFAClient.versionString
To retrieve the version number of the SDK library use the class property UMFAClient.versionString. It will return the version number in semantic versioning format, major.minor.patch.
Swift
Creating a UMFA Client
UMFAClient(ZSMConfig)
UMFAClient(ZSMConfig, relyingParty: RelyingParty)
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| config | ZSMConfig | Configuration for the UMFA client |
| relyingParty | RelyingParty | An instance of RelyingParty to handle WebAuthn authentication (optional) |
Check Enrollment Status
func checkEnrollment(userId: String, completion: @escaping ([String: Any]?, [String: String]?, ZSMError?) -> Void)
Description
Checks if a user has previously registered credentials on this device and retrieves the enrollment status.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| userId | String | The unique identifier for the user |
| completion | ([String: Any]?, [String: String]?, ZSMError?) -> Void | Completion handler called with enrollment data or error |
Returns in Completion Handler
| Parameter Name | Data Type | Description |
|---|---|---|
| data | [String: Any]? | The enrollment status information if user is enrolled |
| metadata | [String: String]? | Additional metadata related to the enrollment status |
| error | ZSMError? | Error object in case of failure; otherwise, nil |
Enrollment
func enroll(userId: String, completion: @escaping ([String: Any]?, [String: String]?, ZSMError?) -> Void)
Description
Initiates the enrollment process for a user, creating and storing credentials on the device.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| userId | String | The unique identifier for the user |
| completion | ([String: Any]?, [String: String]?, ZSMError?) -> Void | Completion handler called with enrollment result or error |
Returns in Completion Handler
| Parameter Name | Data Type | Description |
|---|---|---|
| data | [String: Any]? | The enrollment data including token |
| metadata | [String: String]? | Additional metadata related to the enrollment |
| error | ZSMError? | Error object in case of failure; otherwise, nil |
Authentication
func authenticate(userId: String, completion: @escaping ([String: Any]?, [String: String]?, ZSMError?) -> Void)
Description
Authenticates a previously enrolled user using their device credentials.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| userId | String | The unique identifier for the user |
| completion | ([String: Any]?, [String: String]?, ZSMError?) -> Void | Completion handler called with authentication result or error |
Returns in Completion Handler
| Parameter Name | Data Type | Description |
|---|---|---|
| data | [String: Any]? | The authentication result data, including authentication token |
| metadata | [String: String]? | Additional metadata related to the authentication |
| error | ZSMError? | Error object in case of failure; otherwise, nil |
Unenrollment
func unenroll(userId: String, completion: @escaping (Bool) -> Void)
Description
Unenrolls a user by removing their stored credentials from the device.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| userId | String | The unique identifier for the user to unenroll |
| completion | (Bool) -> Void | Completion handler called with success status of the unenrollment |
Returns in Completion Handler
| Parameter Name | Data Type | Description |
|---|---|---|
| success | Bool | Indicates whether the unenrollment was successful |
Objective-C
Creating a UMFA Client
- (instancetype)initWithConfig:(nonnull ZSMConfig *)config;
- (instancetype)initWithConfig:(nonnull ZSMConfig *)config relyingParty:(nonnull RelyingParty *)relyingParty;
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| config | ZSMConfig * | Configuration for the UMFA client |
| relyingParty | RelyingParty * | An instance of RelyingParty to handle WebAuthn authentication (optional) |
Check Enrollment Status
- (void)checkEnrollment:(NSString *)userId
completion:(void (^)(NSDictionary * _Nullable data, NSDictionary<NSString *, NSString *> * _Nullable metadata, ZSMError * _Nullable error))completion;
Description
Checks if a user has previously registered credentials on this device and retrieves the enrollment status.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| userId | NSString * | The unique identifier for the user |
| completion | void (^)(NSDictionary * _Nullable, NSDictionary<NSString *, NSString *> * _Nullable, ZSMError * _Nullable) | Completion handler called with enrollment data or error |
Returns in Completion Handler
| Parameter Name | Data Type | Description |
|---|---|---|
| data | NSDictionary * _Nullable | The enrollment status information if user is enrolled |
| metadata | NSDictionary<NSString *, NSString *> * | Additional metadata related to the enrollment status |
| error | ZSMError * _Nullable | Error object in case of failure; otherwise, nil |
Enrollment
- (void)enroll:(NSString *)userId
completion:(void (^)(NSDictionary * _Nullable data, NSDictionary<NSString *, NSString *> * _Nullable metadata, ZSMError * _Nullable error))completion;
Description
Initiates the enrollment process for a user, creating and storing credentials on the device.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| userId | NSString * | The unique identifier for the user |
| completion | void (^)(NSDictionary * _Nullable, NSDictionary<NSString *, NSString *> * _Nullable, ZSMError * _Nullable) | Completion handler called with enrollment result or error |
Returns in Completion Handler
| Parameter Name | Data Type | Description |
|---|---|---|
| data | NSDictionary * _Nullable | The enrollment data including token |
| metadata | NSDictionary<NSString *, NSString *> * | Additional metadata related to the enrollment |
| error | ZSMError * _Nullable | Error object in case of failure; otherwise, nil |
Authentication
- (void)authenticate:(NSString *)userId
completion:(void (^)(NSDictionary * _Nullable data, NSDictionary<NSString *, NSString *> * _Nullable metadata, ZSMError * _Nullable error))completion;
Description
Authenticates a previously enrolled user using their device credentials.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| userId | NSString * | The unique identifier for the user |
| completion | void (^)(NSDictionary * _Nullable, NSDictionary<NSString *, NSString *> * _Nullable, ZSMError * _Nullable) | Completion handler called with authentication result or error |
Returns in Completion Handler
| Parameter Name | Data Type | Description |
|---|---|---|
| data | NSDictionary * _Nullable | The authentication result data, including authentication token |
| metadata | NSDictionary<NSString *, NSString *> * | Additional metadata related to the authentication |
| error | ZSMError * _Nullable | Error object in case of failure; otherwise, nil |
Unenrollment
- (void)unenroll:(NSString *)userId
completion:(void (^)(BOOL success))completion;
Description
Unenrolls a user by removing their stored credentials from the device.
Parameters
| Parameter Name | Data Type | Description |
|---|---|---|
| userId | NSString * | The unique identifier for the user to unenroll |
| completion | void (^)(BOOL) | Completion handler called with success status of the unenrollment |
Returns in Completion Handler
| Parameter Name | Data Type | Description |
|---|---|---|
| success | BOOL | Indicates whether the unenrollment was successful |
Out-of-Band Token Validation
For out-of-band validation of the token returned by enroll and authenticate, use the /api/umfa/validate-token endpoint.
HTTP Method
POST
URL
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token
Request Headers
| Header | Value | Description |
|---|---|---|
Content-Type | application/json | Indicates the payload format |
Authorization | Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX | Authorizes the API (API Key expected) |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
application_id | string | Yes | The unique identifier for the request's (server-to-server) application, parsed as a UUID. |
user_id | string | Yes | The unique identifier for the user. |
token | string | Yes | The token received from a previous UMFA authentication operation. |
token_type | string | No | An optional token type specifying the type of validation. Can be "credential" to validate a get() PublicKeyCredential. |
trace_id | string | No | An optional identifier for the validate-token operation. If a trace_id is not provided, then a random trace_id will be generated. |
Successful Response (HTTP 200)
{
"user_id": "janedoe@gmail.com",
"trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143"
}
| Field | Type | Description |
|---|---|---|
user_id | string | The unique identifier for the user that was validated. |
trace_id | string | The trace identifier for the validate-token operation. |
Error Responses
{
"status": 400,
"trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143",
"message": "Validate token failed with: MFA login JWT was invalid: Invalid JWT: There is no user_id claim"
}
| Field | Type | Description |
|---|---|---|
status | integer | The HTTP response code. |
trace_id | string | The trace identifier for the verification operation. |
message | string | Additional information about the validation failure. |
| Status Code | Description | Example Response |
|---|---|---|
400 Bad Request | Incorrectly formed request | { ... "message": "No data provided." } |
401 Unauthorized | Invalid or expired token | { ... "message": "Validate token failed with: MFA login JWT was invalid: Invalid JWT: There is no webauthn_time claim" } |
500 Internal Server Error | Server encountered an issue | { ... "message": "Server encountered an internal error" } |
Example cURL Commands
HTTP Success (200) JWT Validation
$ curl -s - X POST -H "Content-Type: application/json"
-H "Authorization: Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-d '{"application_id": "bf468b21-308f-49d2-9031-83556e0781d2",
"user_id": "janedoe@gmail.com", "token": "eyJ0eX ... Nk9uWg"}'
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token | jq
{
"user_id": "c7d7d44b-385e-4e83-bdd5-37e4fb3c8b7d",
"trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143"
}
HTTP Success (200) Credential Validation
$ curl -s - X POST -H "Content-Type: application/json"
-H "Authorization: Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-d '{"application_id": "bf468b21-308f-49d2-9031-83556e0781d2",
"user_id": "janedoe@gmail.com",
"token":
{
"id":"",
"rawId":"rF2kHiKUQCO0d0Y4Wek9kA",
"response":
{
"clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiNWtMb2tjOXpkZzhuU2RFT2hzV1o5MUwzZTNGdjlqbERlRU9KcF93SnRkayIsIm9yaWdpbiI6Imh0dHBzOi8venNtLmFwcCJ9","authenticatorData":"ZxcNEwlh6TBKTTC5FMSFPTOboOZWzGeOSiYY7rm67WUFAAAAAQ","signature":"UOOoSBAwemLSPvqLVG2MDw41cqKLcHEUp4LAFGuvrVPsR1GWBYTWtmpqG_Jtjn-DXq5tGGAE58SYvu7uvcw7oHqquoNG4VEdm4Tz7UNe5kdSoc3RFpEGGDLCIz28iKXaBPbv3jdHi4xGoCIJKIIeHyh0-g7LUb4ZjYFIZHyXds7cdH9ozXRt5ERWUVvH1axDnPDKpntGQXG8FC4VXd0Rc01-4bBklNSGHOVgbO-Rpm8HgeFj3J4uOZDJ0xP7pnIkwOo5Uw_0ZO9xI66S8NQEtVzXVUKXs98f38LpLiLGEPlWtr_RIdf9xgsmHx-oVRJxC37gzV2ydSGKJaV6bNsXOw"},
"type":"public-key"
}
},
"token-type": "credential"}'
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token | jq
{
"user_id": "c7d7d44b-385e-4e83-bdd5-37e4fb3c8b7d",
"trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143"
}
Bad Request (400)
$ curl -s - X POST -H "Content-Type: application/json"
-H "Authorization: Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-d '{"application_id": "bf468b21-308f-49d2-9031-83556e0781d2",
"user_id": "janedoe@gmail.com"}'
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token | jq
{
"status": 400,
"trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143",
"message": "Invalid data provided"
}
Unauthorized (401)
$ curl -s - X POST -H "Content-Type: application/json"
-H "Authorization: Bearer XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
-d '{"application_id": "bf468b21-308f-49d2-9031-83556e0781d2",
"user_id": "janedoe@gmail.com", "token": "eyJ0eX ... Nk9uWg"}'
$ZSM_AUTHENTICATOR_HOST/api/umfa/validate-token | jq
{
"status": 401,
"trace_id": "7a626fe9-ce25-4b87-8eb2-b12a7ee20143",
"message": "Validate token failed with: MFA login JWT was invalid: Invalid JWT: Invalid claim: The token has expired: 2024-12-10 18:41:03.0 +00:00:00"
}
Validate Token Failures
The server's token validation can fail for two general reasons:
- HTTP 400 Response: The request was malformed (i.e.,
tokenwas not included) - HTTP 401 Response: The token was invalid, which could have various causes
- Token's
user_iddid not match the supplieduser_id - Token has expired (the token's "exp" claim has passed)
- Token was missing required claims ("iss", "sub", "iat", "exp", "user_id", "webauthn_time")
- Token was not signed by the expected ZSM server's certificate
- Token was not a valid PublicKeyCredential when supplied
"token_type" = "credential"
- Token's
Decoded JWT
Below, we illustrate an example of a decoded UMFA JWT (Header and Payload).
The validation performs standard JWT validation like signature, liveness,
and structure. The validation also ensures that the payload claim user_id
matches that of the supplied user_id.
{
"typ": "JWT",
"alg": "RS256",
"iss": "Ideem::Authenticator"
}
{
"sub": "UMFA_login",
"iss": "Ideem::Authenticator",
"aud": [
"Ideem::Authenticator",
"Ideem::ZSM",
"Ideem::ZSM_CLI"
],
"iat": 1729280408,
"exp": 1729366808,
"jti": "042142c1-40c8-4d9b-bf5e-1fa84e0f3f03",
"user_id": "c7d7d44b-385e-4e83-bdd5-37e4fb3c8b7d",
"userpw_time": "2024-10-18T19:40:07.053364351+00:00",
"webauthn_time": "2024-10-18T19:40:08.053364351+00:00"
}