Local users (/localusers/)
URL: https://[server_name]/api/[api_version]/localusers/
This endpoint represents local user resource, namely a user account. This resource can be found in the FortiAuthenticator GUI under Authentication > Local Users. This API is for use by third-party provisioning systems.
Supported fields
Field | Display name | Type | Required | Other restrictions |
---|---|---|---|---|
username | Username | string | Yes | max length = 253, contains only letters, numbers and @/./+/-/_ characters |
address | Address | string | No | max length = 80 |
city | City | string | No | max length = 40 |
country | Country | string | No | Must be a country code from ISO-3166 list |
custom1 | Custom user field 1 | string | No | max length = 255 |
custom2 | Custom user field 2 | string | No | max length = 255 |
custom3 | Custom user field 3 | string | No | max length = 255 |
E-mail address | string | No | Must be a valid e-mail address | |
first_name | First name | string | No | max length = 30 |
last_name | Last name | string | No | max length = 30 |
active | Account Status | boolean | No | |
reason |
Disable reason |
Interger |
No |
Default is 0. One of 0 (manually disabled), 1 (account inactivity), 2 (too many failed attempts), 3 (account expiry), 4 (password expiry), 5 (FTM activation expiry), 6 (revoked token), 7 (usage limit exceeded), or 8 (pending administrator approval). |
mobile_number | Mobile number | string | No | max length = 25, must follow international number format: +[country_code]-[number] |
phone_number | Mobile number | string | No | max length = 25 |
state | State or province | string | No | max length = 40 |
user_groups | Local user groups that this user is a member of | list | No | List of user groups URI. Read Only. See usergroups or localgroup-memberships to make relations. |
token_auth | Token Auth | boolean | No | Whether second factor authentication should be enabled. If 'true', token_type is required. |
token_type | Token Type | string | No | One of ftk, ftm, ftc, email, sms, or dual. If email is chosen, email is required. If sms is chosen, mobile_number is required. Both are required if dual is selected. |
token_serial | Token Serial | string | No | If token_type is ftm, or ftk, and this is not present or blank, the next available token will be assigned. |
ftm_act_method | FTM Activation Delivery Method | string | No | One of email or sms. If email is chosen, email is required. If sms is chosen, mobile_number is required. |
ftk_only | Enable FortiToken-only authentication | boolean | No | If set, token_auth must be true, and token_type must be either ftk or ftm. If this field is changed to false, email must be set to reset user's password and send a new random password. Mutually exclusive with password. |
expires_at | Expiration time | string | No | ISO-8601 formatted user expiration time in UTC. Specified time should be formatted using ISO-8601 with a timezone offset. If timezone info is not set, time is always assumed to be in UTC. To remove an expiration time, set this field to an empty string. Time must be at least an hour in the future. |
token_fas |
Token from FortiAnalyzer |
boolean |
No |
True if token is issued from FortiAnalyzer. The default is false. |
Additionally, when creating a new user, the following field is available:
Field | Display name | Type | Required | Other restrictions |
---|---|---|---|---|
password | Password | string | No | max length = 50 |
change_password |
Change password on next logon |
boolean |
No |
|
recovery_by_question |
Allow password recovery with security question |
boolean |
No |
|
recovery_question |
Password recovery security question |
string |
No |
Required if recovery_by_question is true. |
recovery_answer |
Password recovery security answer |
string |
No |
Required if recovery_by_question is true. |
Allowed methods
HTTP method | Resource URI | Action |
---|---|---|
GET | /api/v1/localusers/ | Get all regular local users. |
GET | /api/v1/localusers/[id]/ | Get a specific local user with ID. |
POST | /api/v1/localusers/ |
Create a new local user. Notes:
|
POST | /api/v1/localusers/[id]/sendoobtoken/ | Send an out-of-band token code (email/SMS token) to a local user. |
POST | /api/v1/localusers/[id]/verifyrecoveryanswer/ | Verify the recovery answer for a specific local user. Note: recovery_answer must be included. Returns status 202 if the supplied recovery_answer parameter is correct, or 404 if not correct. |
PATCH | /api/v1/localusers/[id]/ | Update specified fields for a specific local user with ID. |
DELETE | /api/v1/localusers/[id]/ | Delete a local user. |
Allowed filters
Field | Lookup expressions | Values |
---|---|---|
username |
exact, iexact, contains, icontains, in
|
|
abridged |
Use |
|
first_name |
exact, iexact, contains, icontains
|
|
last_name |
exact, iexact, contains, icontains
|
|
exact, iexact, contains, icontains, in
|
||
active |
exact
|
|
city |
exact, iexact, contains, icontains
|
|
state |
exact, iexact, contains, icontains
|
|
country |
exact, iexact, contains, icontains
|
|
token_type |
ftk, ftm, ftc, email, sms
|
|
token_serial |
exact, iexact
|
Third-party integration: FTM provisioning
For integration with a third-party authentication server which needs to manage token validation, it is possible for the FortiAuthenticator to return FTM seed during provisioning. However, certain conditions must be met:
- Seed may only be returned when creating a new local user via POST method and when provisioning an FTM to an existing user via PATCH method.
- A GET URL parameter (returnseed=1) needs to be specified to explicitly tell FortiAuthenticator to return an encrypted seed for the token (e.g. https://[server_name]/api/v1/localusers/2/?returnseed=1).
- A seed encryption passphrase must be specified in FortiGuard settings.
The seed is encrypted and returned as a PSKC XML file string according to RFC 6030. The key is derived from the configured passphrase using the PBKDF2 key derivation function (32 byte key length, 1000 iterations), encrypted with AES 256 CBC encryption, and signed with a SHA256 HMAC.
Whenever an FTM is provisioned, its activation code will be returned as well.
List all local users
JSON query
- JSON specified via GET
curl -k -v -u "admin:zeyDZXmP6GbKcerqdWWEYNTnH2TaOCz5HTp2dAVS" https://192.168.0.122/api/v1/localusers/?format=xml
- JSON specified via Accept Header
curl -k -v -u "admin:zeyDZXmP6GbKcerqdWWEYNTnH2TaOCz5HTp2dAVS" -H 'Accept: application/xml' https://192.168.0.122/api/v1/ localusers/
Response
< HTTP/1.1 200 OK
< Date: Mon, 09 Jun 2014 20:14:23 GMT
< Server: Apache
< Vary: Accept,Accept-Language,Cookie
< X-Frame-Options: SAMEORIGIN
< Content-Language: en
< Cache-Control: no-cache
< Transfer-Encoding: chunked
< Content-Type: application/json
<
* Connection #0 to host 192.168.0.122 left intact
* Closing connection #0
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 2}, "objects": [{"address": "", "city": "", "country": "", "custom1": "", "custom2": "", "custom3": "", "email": "", "first_name": "", "id": 5, "last_name": "", "mobile_number": "", "phone_number": "", "resource_uri": "/api/v1/localusers/5/", "state": "", "token_auth": false, "token_serial": "", "token_type": null, "user_groups": ["/api/v1/usergroups/9/", "/api/v1/usergroups/8/"], "username": "test_user2"}, {"address": "", "city": "", "country": "", "custom1": "", "custom2": "", "custom3": "", "email": "", "first_name": "", "id": 4, "last_name": "", "mobile_number": "", "phone_number": "", "resource_uri": "/api/v1/localusers/4/", "state": "", "token_auth": false, "token_serial": "", "token_type": null, "user_groups": ["/api/v1/usergroups/8/"], "username": "test_user"}]}
Here you will notice that there are 2 users defined “test_user” and “test_user2”. Note that admin users are not returned by the localusers query.
Create local user
JSON query
- JSON specified via Accept Header
curl -k -v -u "admin:zeyDZXmP6GbKcerqdWWEYNTnH2TaOCz5HTp2dAVS" -X POST -d '{"username":"test_user3","password":"testpassword","email":"test_user3@example.com","mobile":"+44-1234567890"}' -H 'Content-Type: application/json' https://192.168.0.122/api/v1/localusers/
Response
< HTTP/1.1 201 CREATED
< Date: Mon, 09 Jun 2014 20:29:20 GMT
< Server: Apache
< Vary: Accept,Accept-Language,Cookie
< X-Frame-Options: SAMEORIGIN
< Content-Language: en
< Location: https://192.168.0.122/api/v1/localusers/6/
< Content-Length: 0
< Content-Type: text/html; charset=utf-8
Verify user creation
curl -k -v -u "admin:zeyDZXmP6GbKcerqdWWEYNTnH2TaOCz5HTp2dAVS" https://192.168.0.122/api/v1/localusers/?format=json
< HTTP/1.1 200 OK
< Date: Mon, 09 Jun 2014 20:30:26 GMT
< Server: Apache
< Vary: Accept,Accept-Language,Cookie
< X-Frame-Options: SAMEORIGIN
< Content-Language: en
< Cache-Control: no-cache
< Transfer-Encoding: chunked
< Content-Type: application/json
<
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 3}, "objects": [{"address": "", "city": "", "country": "", "custom1": "", "custom2": "", "custom3": "", "email": "", "first_name": "", "id": 5, "last_name": "", "mobile_number": "", "phone_number": "", "resource_uri": "/api/v1/localusers/5/", "state": "", "token_auth": false, "token_serial": "", "token_type": null, "user_groups": ["/api/v1/usergroups/9/", "/api/v1/usergroups/8/"], "username": "test_user2"}, {"address": "", "city": "", "country": "", "custom1": "", "custom2": "", "custom3": "", "email": "", "first_name": "", "id": 4, "last_name": "", "mobile_number": "", "phone_number": "", "resource_uri": "/api/v1/localusers/4/", "state": "", "token_auth": false, "token_serial": "", "token_type": null, "user_groups": ["/api/v1/usergroups/8/"], "username": "test_user"}, {"address": "", "city": "", "country": "", "custom1": "", "custom2": "", "custom3": "", "email": "test_user3@example.com", "first_name": "", "id": 6, "last_name": "", "mobile_number": "", "phone_number": "", "resource_uri": "/api/v1/localusers/6/", "state": "", "token_auth": false, "token_serial": "", "token_type": null, "user_groups": [], "username": "test_user3"}]}
Modify local user
JSON query
- JSON specified via Accept Header
Modify the newly created user “test_user3” aka User ID == 6 using the PATCH command.
curl -k -v -u "admin:zeyDZXmP6GbKcerqdWWEYNTnH2TaOCz5HTp2dAVS" -X PATCH -d '{"custom1":"example","country":"GB"}' -H 'Content-Type: application/json' https://192.168.0.122/api/v1/localusers/6/
Response
< HTTP/1.1 202 ACCEPTED
< Date: Mon, 09 Jun 2014 21:07:28 GMT
< Server: Apache
< Vary: Accept,Accept-Language,Cookie
< X-Frame-Options: SAMEORIGIN
< Content-Language: en
< Content-Length: 0
< Content-Type: text/html; charset=utf-8
Delete local user
Send an HTTP DELETE to the resource with the user ID to delete a local user, in the following format:
https://<server-name>/api/v1/localusers/5/
A successful response will show in the following format:
HTTP/1.1 204 NO CONTENT
Applying filters
List specific local user
JSON query
- JSON specified via GET
curl -k -v -u "admin:zeyDZXmP6GbKcerqdWWEYNTnH2TaOCz5HTp2dAVS" “https://192.168.0.122/api/v1/localusers/?format=json&username=test_user3”
- JSON specified via Accept Header
curl -k -v -u "admin:zeyDZXmP6GbKcerqdWWEYNTnH2TaOCz5HTp2dAVS" -H 'Accept: application/json' “https://192.168.0.122/api/v1/localusers/?username=test_user3”
Response
< HTTP/1.1 200 OK
< Date: Tue, 10 Jun 2014 11:06:20 GMT
< Server: Apache
< Vary: Accept,Accept-Language,Cookie
< X-Frame-Options: SAMEORIGIN
< Content-Language: en
< Cache-Control: no-cache
< Transfer-Encoding: chunked
< Content-Type: application/json
<
* Connection #0 to host 192.168.0.122 left intact
* Closing connection #0
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}, "objects": [{"address": "", "city": "", "country": "", "custom1": "example", "custom2": "", "custom3": "", "email": "test_user3@example.com", "first_name": "", "id": 6, "last_name": "", "mobile_number": "", "phone_number": "", "resource_uri": "/api/v1/localusers/6/", "state": "", "token_auth": false, "token_serial": "", "token_type": null, "user_groups": [], "username": "test_user3"}]}[
View all users from Country=GB
JSON query
- JSON specified via Accept Header
View all users from the country GB (Great Britain).
curl -k -v -u "admin:zeyDZXmP6GbKcerqdWWEYNTnH2TaOCz5HTp2dAVS" -H 'Accept: application/json' "https://192.168.0.122/api/v1/localusers/?country=GB"
Response
< HTTP/1.1 200 OK
< Date: Tue, 10 Jun 2014 11:14:39 GMT
< Server: Apache
< Vary: Accept,Accept-Language,Cookie
< X-Frame-Options: SAMEORIGIN
< Content-Language: en
< Cache-Control: no-cache
< Transfer-Encoding: chunked
< Content-Type: application/json
<
* Connection #0 to host 192.168.0.122 left intact
* Closing connection #0
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 2}, "objects": [{"address": "", "city": "", "country": "GB", "custom1": "example", "custom2": "", "custom3": "", "email": "test_user3@example.com", "first_name": "", "id": 6, "last_name": "", "mobile_number": "", "phone_number": "", "resource_uri": "/api/v1/localusers/6/", "state": "", "token_auth": false, "token_serial": "", "token_type": null, "user_groups": [], "username": "test_user3"}, {"address": "", "city": "", "country": "GB", "custom1": "example", "custom2": "", "custom3": "", "email": "", "first_name": "", "id": 5, "last_name": "", "mobile_number": "", "phone_number": "", "resource_uri": "/api/v1/localusers/5/", "state": "", "token_auth": false, "token_serial": "", "token_type": null, "user_groups": ["/api/v1/usergroups/9/", "/api/v1/usergroups/8/"], "username": "test_user2"}]}[
Add RADIUS attributes to local users
URL: https://[server_name]/api/[api_version]/localusers/[id]/radiusattributes/
This resource can only be used for RADIUS attribute of local users. All the fields are case-sensitive.
Supported fields
Field | Display name | Type | Required | Read only | Other restrictions |
---|---|---|---|---|---|
owner | owner | string | No | Yes | - |
vendor | vendor | string | No | No | max length = 40, default = "Default" |
attribute | RADIUS attribute | string | Yes | No | max length = 255 |
attr_val | Attribute Value | Depends on RADIUS attribute | Yes | No | max length = 255 |
Allowed methods
HTTP method | Resource URI | Action |
---|---|---|
GET | /api/v1/localusers/[id]/radiusattributes/ | Get all Radius Attributes for a specific Local User |
GET | /api/v1/localusers/[id]/radiusattributes/[attribute_id]/ | Get a Radius Attribute for a specific Local User |
POST | /api/v1/localusers/[id]/radiusattributes/ | Create a new Radius Attribute for a specific Local User |
PUT | /api/v1/localusers/[id]/radiusattributes/ | Update all Radius Attributes that belong to a Local User |
PATCH | /api/v1/localusers/[id]/radiusattributes/[attribute_id]/ | Update fields of a Radius Attribute |
DELETE | /api/v1/localusers/[id]/radiusattributes/ | Delete all Radius Attributes from a specific Local User |
DELETE | /api/v1/localusers/[id]/radiusattributes/[attribute_id]/ | Delete a Radius Attribute from a specific Local User |
Allowed filters
Field | Lookup expressions | Values |
---|---|---|
vendor |
exact
|
- |
attribute |
exact
|
- |
attr_value |
exact, iexact, contains, icontains, in
|
- |