Skip to main content
msundman
Visitor III
Jan 14, 2023 9:21 PM UTC
Question

FortiSASE API cURL script

As FortiSASE currently lacks an official public API, I thought I'd share a little bash-script I just wrote that uses cURL to login to FortiSASE via SAML/SSO and can then access the backend REST(ish)-API used by the FortiSASE portal natively.

 

I needed this to automate the process of adding ZTNA destinations as part of our customers build pipeline.

Please ignore the ugly grep/sed's and just see this as proof-of-concept code for inspiration.

 

Also be aware that as the API is currently not documented or intended to be used by end customers, I assume Fortinet will not give you any support if you experience problems with the API, so please use this code on your own risk.

 

 

 

 

 

#!/bin/bash ################################################################################# # CURL snippet to use SAML IAM Login to FortiSASE to consume it's REST API. #################################################################################  curl_opts="-s --cookie-jar saseCookieFile --cookie saseCookieFile --insecure" fortisase_baseurl="https://portal.prod.fortisase.com" fortisase_loginurl="https://portal.prod.fortisase.com/saml/ssoLogin" fortisase_apiloginurl="https://portal.prod.fortisase.com/api/v1/system/login/sso" fortisso_baseurl="https://customersso1.fortinet.com" fortisso_loginurl="https://customersso1.fortinet.com/saml-idp/iam_login/" forti_account="123456" forti_username="firstname.lastname" forti_password="xxxxx"  # Delete old Cookie-file: rm saseCookieFile &> /dev/null  # Get FortiSASE pre-login page and save SAMLRequest: echo "GET ${fortisase_baseurl}/pre-login" saml_loginurl=$(curl -i ${curl_opts} ${fortisase_baseurl}/pre-login | grep Location | sed "s/Location: //g" | tr -d $'\r') saml_request=$(echo "${saml_loginurl}" | sed 's/^.*\?SAMLRequest=/\?SAMLRequest=/')  # Get SAML pre-login page and save sessionid Cookie: echo "GET ${saml_loginurl}" curl ${curl_opts} ${saml_loginurl} &> /dev/null  # Get Fortinet IAM Login page and save CSRFTOKEN in login form: echo "GET ${fortisso_loginurl}/?SAMLRequest=xxxx" res=$(curl ${curl_opts} ${fortisso_loginurl}/${saml_request}) csrftoken=`echo "${res}" | grep csrfmiddlewaretoken | awk -F '"' '{print $6}' `  # Perform Forinet IAM SAML Login and save SAMLResponse: echo "POST ${fortisso_loginurl}" data="csrfmiddlewaretoken=${csrftoken}&next=/saml-idp/portal/&account=${forti_account}&username=${forti_username}&password=${forti_password}" res=$(curl ${curl_opts} --location --referer ${fortisso_baseurl} --data ${data} ${fortisso_loginurl}${saml_request}) saml_response=`echo "${res}" | grep SAMLResponse | awk -F '"' '{print $6}'`  # Perform SAML SSO Login to FortiSASE to get x-auth-token Cookie: echo "POST ${fortisase_loginurl}" res=$(curl -i ${curl_opts} --location --referer ${fortisso_baseurl} --data-urlencode RelayState= --data-urlencode SAMLResponse=${saml_response} ${fortisase_loginurl}) xauthtoken=$(echo "${res}" | grep x-auth-token | sed -n 's/.*=\([^;]*\);.*/\1/p')  # Parse SAMLResponse and create API Login JSON data: echo "Parse SAMLResponse and generate JSON Login data" saml_decoded=$(echo "${saml_response}" | base64 -d | xmllint --format -) iam_account_alias=$(echo "${saml_decoded}" | grep -A1 IAM_account_alias | sed -n 2p | sed -n 's/.*>\(.*\)<.*/\1/p') iam_account_name=$(echo "${saml_decoded}" | grep -A1 IAM_account_name | sed -n 2p | sed -n 's/.*>\(.*\)<.*/\1/p') iam_user_name=$(echo "${saml_decoded}" | grep -A1 IAM_username | sed -n 2p | sed -n 's/.*>\(.*\)<.*/\1/p') nameID=$(echo "${saml_decoded}" | grep -A1 idp_user_id | sed -n 2p | sed -n 's/.*>\(.*\)<.*/\1/p') data=' {     "auth_type": "iam",     "authentication_status": "password only",     "company": {         "name": ""     },     "iam_account_alias": "IAM_ACCOUNT_ALIAS",     "iam_account_name": "IAM_ACCOUNT_NAME",     "iam_user_name": "IAM_USER_NAME",     "name": "IAM_USER_NAME",     "nameID": "NAMEID",     "principal": "IAM_USER_NAME",     "root": false,     "tenant": {         "account_id": "IAM_ACCOUNT_NAME",         "root_principal": "IAM_ACCOUNT_NAME"     } }' data=$(sed "s/IAM_ACCOUNT_ALIAS/$iam_account_alias/g" <<< "$data") data=$(sed "s/IAM_ACCOUNT_NAME/$iam_account_name/g" <<< "$data") data=$(sed "s/IAM_USER_NAME/$iam_user_name/g" <<< "$data") data=$(sed "s/NAMEID/$nameID/g" <<< "$data")  # Login to FortiSASE API to get access and refresh tokens: echo "POST ${fortisase_apiloginurl}" response=$(curl ${curl_opts} --referer ${fortisase_baseurl}/sso-login -H "auth-token: ${xauthtoken}" -H "Content-Type: application/json" -d "${data}" ${fortisase_apiloginurl}) access_token=$(echo "${response}" | jq -r .data.access_token) refresh_token=$(echo "${response}" | jq -r .data.refresh_token)  # Perform API to get list of ZTNA destinations: curl -s -H "Authorization: Bearer ${access_token}" https://portal.prod.fortisase.com/endpoint/fct/api/public/v1/sase_to_ems/profiles/ztna/2/get | jq .

 

 

 

 

 

1 reply

TuncayBAS
Explorer
Aug 29, 2024 4:04 PM UTC

Thanks bro

Thought Leadership. Security Summit. Thursday, November 12th, PGA National Resort, Palm Beach Gardens, FL.
Security Operations Summit: Modernize SecOps. Operate AI-Native.AMER: November 4 | 9:00 AM PST. India and SAARC: November 5 | 10:00 AM IST. EMEA: November 5 | 10:30 AM CET. APAC: November 5 | 11:00 AM SGT