FortiAuthenticator

This integration allows you to manage the user configuration on FortiAuthenticator.

Authentication & Identity Management · FortiAuthenticator

Details

IDFortiAuthenticator
ProviderFortinet
CategoryAuthentication & Identity Management
From Version6.0.0
Docker Imagedemisto/python3:3.12.12.7090913
Supported ModulesAgentix XSIAM

README

FortiAuthenticator provides centralized authentication services.
Seamless secure two-factor/OTP authentication across the organization in conjunction with FortiToken.

This integration was integrated and tested with versions 4.0 - 6.3.0 of FortiAuthenticator.

Enable API Access for admin user on FortiAuthenticator

Steps to get the Access Key for the API authentication

** Note: Ensure email routing is working (i.e. the FortiAuthenticator is able to send mail) beforehand as the API Key will be delivered by email.

On the FortiAuthenticator WebUI, create a new user for API or edit an existing one

Under the Authentication > User Management, edit the user:

  1. Under User Role, select Administrator.
  2. Enable Web service access.
  3. Under User Information, please ensure there’s a valid email address.
  4. Click OK to save the details.
  5. The Web Service Access Secret Key used to authenticate to the API is emailed to the user.

Supported user types

  • Local Users
  • LDAP Users

Configure FortiAuthenticator on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for FortiAuthenticator.
  3. Click Add instance to create and configure a new integration instance.

    Parameter Description Required
    server_url Server URL True
    credentials Username True
    credentials Access Key True
    insecure Trust any certificate (not secure) False
    proxy Use system proxy settings False
  4. Click Test to validate the URLs, credentials, and connection.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

fortiauthenticator-get-user

Input

Argument Name Description Required
user_type The user type: localusers (Local Users), ldapuser (Remote Users) Required
email The user’s email that is defined in the User Information on FortiAuthenticator Optional
username The username that is defined in the User Information on FortiAuthenticator Optional
token_serial The serial no. of the assigned Token on FortiAuthenticator Optional
  • Note: You need either an email, username, or token_serial input in order for the command to work.

Context Output

Path Type Description
FortiAuthenticator.user Unknown The user information
FortiAuthenticator.user.id Unknown The user’s id on FortiAuthenticator
FortiAuthenticator.user.username Unknown The user’s username
FortiAuthenticator.user.email Unknown The user’s email address
FortiAuthenticator.user.active Unknown The user’s active status (true = enabled, false = disabled)
FortiAuthenticator.user.token_auth Unknown The token auth status
FortiAuthenticator.user.token_type Unknown The token type
FortiAuthenticator.user.token_serial Unknown The token serial number

Command Example

!fortiauthenticator-get-user user_type=localusers email=test_user@example.com

Context Example

{
    "FortiAuthenticator": {
        "user": {
            "active": "true",
            "email": "test_user@example.com",
            "id": "7",
            "username": "test_user",
            "token_auth": "true",
            "token_type": "ftm",
            "token_serial": "FTKMOB123456789A"

        }
    }
}

Human Readable Output

FortiAuthenticator User Info

id username email active token_auth token_type token_serial
7 test_user test_user@example.com true true ftm FTKMOB123456789A

fortiauthenticator-update-user

Input

Argument Name Description Required
user_type The user type: localusers (Local Users), ldapuser (Remote Users) Required
email The user’s email that is defined in the User Information on FortiAuthenticator Optional
username The username that is defined in the User Information on FortiAuthenticator Optional
active Define user’s active status: false = Disabled, true = enabled Required
  • Note: You need either an email or username input in order for the command to work.

Context Output

Path Type Description
FortiAuthenticator.user Unknown The user information
FortiAuthenticator.user.id Unknown The user’s id on FortiAuthenticator
FortiAuthenticator.user.username Unknown The user’s username
FortiAuthenticator.user.email Unknown The user’s email address
FortiAuthenticator.user.active Unknown The user’s active status (true = enabled, false = disabled)
FortiAuthenticator.user.token_auth Unknown The token auth status
FortiAuthenticator.user.token_type Unknown The token type
FortiAuthenticator.user.token_serial Unknown The token serial number

Command Example

!fortiauthenticator-update-user active=false user_type=localusers email=test_user@example.com

Context Example

{
    "FortiAuthenticator": {
        "user": {
            "active": "false",
            "email": "test_user@example.com",
            "id": "7",
            "username": "test_user",
            "token_auth": "true",
            "token_type": "ftm",
            "token_auth": "FTKMOB123456789A"
        }
    }
}

Human Readable Output

Updated FortiAuthenticator User Info

id username email active token_auth token_type token_serial
7 test_user test_user@example.com false true ftm FTKMOB123456789A

Configuration parameters

  • server — Server URL (e.g. https://192.168.0.1) (required)
  • credentials — Username (required)
  • unsecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (2)

  • fortiauthenticator-get-user

    Get the user details for specific user by email.

  • fortiauthenticator-update-user

    Update the active status for specific user by email

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

""" IMPORTS """

import json

import requests

# Disable insecure warnings
import urllib3

urllib3.disable_warnings()

""" GLOBALS/PARAMS """

USER_NAME = demisto.params().get("credentials").get("identifier")
PASSWORD = demisto.params().get("credentials").get("password")
SERVER = (
    demisto.params()["server"][:-1]
    if (demisto.params()["server"] and demisto.params()["server"].endswith("/"))
    else demisto.params()["server"]
)
USE_SSL = not demisto.params().get("unsecure", False)
BASE_URL = SERVER + "/api/v1/"

# remove proxy if not set to true in params
if not demisto.params().get("proxy"):
    # Remove proxy environment variables if they exist
    for proxy_var in ["HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy"]:
        os.environ.pop(proxy_var, None)


""" COMMANDS + REQUESTS FUNCTIONS """


@logger
def test_module():
    """
    Perform basic login and logout operation, validate connection.
    """
    r = requests.get(BASE_URL, auth=(USER_NAME, PASSWORD), verify=USE_SSL)
    return r.status_code == 200


@logger
def get_user_command():
    user_context = []
    userType = demisto.args().get("user_type")
    userItems = get_user_request(userType)

    if userItems:
        user_context.append(
            {
                "id": userItems["objects"][0]["id"],
                "username": userItems["objects"][0]["username"],
                "email": userItems["objects"][0]["email"],
                "active": userItems["objects"][0]["active"],
                "token_auth": userItems["objects"][0]["token_auth"],
                "token_type": userItems["objects"][0]["token_type"],
                "token_serial": userItems["objects"][0]["token_serial"],
            }
        )

        markdown = "FortiAuthenticator\n"
        markdown += tableToMarkdown(
            "FortiAuthenticator User Info",
            user_context,
            headers=["id", "username", "email", "active", "token_auth", "token_type", "token_serial"],
        )
        results = CommandResults(
            readable_output=markdown, outputs_prefix="FortiAuthenticator.user", outputs_key_field="id", outputs=user_context
        )
        return_results(results)
    else:
        markdown = "No such user.\n"
        results = CommandResults(readable_output=markdown)
        return_results(results)


@logger
def get_user_request(userType):
    email = demisto.args().get("email")
    username = demisto.args().get("username")
    token_serial = demisto.args().get("token_serial")

    if email:
        params = {"format": "json", "email": email}
    elif username:
        params = {"format": "json", "username": username}
    elif token_serial:
        params = {"format": "json", "token_serial": token_serial}
    else:
        return False

    res = requests.get(BASE_URL + userType, params=params, auth=(USER_NAME, PASSWORD), verify=USE_SSL)
    tmp = res.json()
    if tmp["meta"]["total_count"] == 0:
        return False
    else:
        return res.json()


@logger
def update_user_command():
    user_context = []
    active = demisto.args().get("active")
    userType = demisto.args().get("user_type")
    userItems = get_user_request(userType)

    if userItems:
        userURI = str(userItems["objects"][0]["resource_uri"])
        if active == "true":
            userDict = {"active": True}
        else:
            userDict = {"active": False}

        jsonData = json.dumps(userDict)

        res = requests.patch(SERVER + userURI, data=jsonData, auth=(USER_NAME, PASSWORD), verify=USE_SSL)

        if res.status_code == 202:
            user_context.append(
                {
                    "id": userItems["objects"][0]["id"],
                    "username": userItems["objects"][0]["username"],
                    "email": userItems["objects"][0]["email"],
                    "active": active,
                    "token_auth": userItems["objects"][0]["token_auth"],
                    "token_type": userItems["objects"][0]["token_type"],
                    "token_serial": userItems["objects"][0]["token_serial"],
                }
            )

            markdown = "FortiAuthenticator\n"
            markdown += tableToMarkdown(
                "Updated FortiAuthenticator User Info",
                user_context,
                headers=["id", "username", "email", "active", "token_auth", "token_type", "token_serial"],
            )
            results = CommandResults(
                readable_output=markdown, outputs_prefix="FortiAuthenticator.user", outputs_key_field="id", outputs=user_context
            )
        else:
            results = CommandResults(readable_output="Fail to update user.\n")
    else:
        results = CommandResults(readable_output="No such user for update.\n")
    return_results(results)


""" COMMANDS MANAGER / SWITCH PANEL """

LOG(f"command is {demisto.command()}")

try:
    if demisto.command() == "test-module":
        # This is the call made when pressing the integration test button.
        test_module()
        demisto.results("ok")
    elif demisto.command() == "fortiauthenticator-get-user":
        get_user_command()
    elif demisto.command() == "fortiauthenticator-update-user":
        update_user_command()

# Log exceptions and return errors
except Exception:
    demisto.error(traceback.format_exc())  # print the traceback
    return_error(f"Failed to execute {demisto.command()} command.\nError:\n{traceback.format_exc()}")