Like what you see? Have a play with our trial version.

Error rendering macro 'rw-search'

null

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Current »

When integrating Yellowfin with a host application, it is necessary to provide a seamless jump between the host application and the Yellowfin interface. This might include integrating the full Yellowfin UI, or embedding individual pieces of content within the host application. In either case, an existing Yellowfin session is required to suppress Yellowfin from prompting the user to login each time. This can be achieved with Yellowfin’s SSO services. 

Yellowfin’s SSO end-point allows for generating a single-use token that allows the user to by-pass the user authentication screen in Yellowfin.

The standard use case is that a user will already be authenticated with the host application (where Yellowfin is integrated or embedded).  When the user attempts to enter an area of the host application that requires Yellowfin, the host application can make a server-side call to Yellowfin to generate a single-use token. Once the token is retrieved, it can be added to either the Yellowfin logon URL, or embedded in JS API code. The user can then be redirected to the URL or a page with embedded content.

To bypass the standard Yellowfin login screen, the token can be added to this URL:

http://<yellowfin-server-address>/logon.i4?LoginWebserviceId=<tokenId>


Generating an SSO Login Token

A Login SSO token can be retrieved using the GET /api/login-tokens end-point, Create Login Token. The payload for this request is of the form:

{

  "signOnUser": {

    "userName": "admin@yellowfin.com.au",

    "password": "test",

    "clientOrgRef": "CLIENT1"

  },

  "loginParameters": [

    "YFTOOLBAR=FALSE",

    "ENTRY=VIEWDASHBOARD",

    "DASHBOARDUUID=5678f33c-c666-4972-8976-9c489accf73b"

  ],

  "noPassword": false,

  "customParameters": "Some custom integration value"

}

The signOnUser attribute is required, the other attributes are optional. The contents of the signOnUser attribute will be the credentials of the user we are logging in. The clientOrgRef is only required when logging into a tenant. 

The following examples return the SSO token that can be used to log a user into Yellowfin without prompting them for the username and password. This example uses the standard paradigm of using a REST Access Token.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a user using the Yellowfin REST API
 */
public class CreateSSOTokenWithAccessToken {
    public static void main(String[] args) throws Exception {

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String userToLogin = ""user1@yellowfin.com.au"";
        String userToLoginPassword = ""test"";

        String createUserPayload = ""{\n""
                + ""  \""signOnUser\"": {\n""
                + ""    \""userName\"": \""""+ userToLogin + ""\"",\n""
                + ""    \""password\"": \""""+ userToLoginPassword + ""\""\n""
                + ""  }\n""
                + ""}"";

        String token = generateToken(host, restUsername, restPassword);

        System.out.println(""Payload: "" + createUserPayload);

        Content c = Request.post(host + ""/api/login-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(createUserPayload, null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement securityToken = jsonObject.get(""securityToken"");

        System.out.println(""SSO Token: "" + securityToken);

    }

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class CreateSSOTokenWithAccessToken
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string userToLogin = ""user1@yellowfin.com.au"";
            string userToLoginPassword = ""test"";

            string createUserPayload = ""{\n""
                + ""  \""signOnUser\"": {\n""
                + ""    \""userName\"": \"""" + userToLogin + ""\"",\n""
                + ""    \""password\"": \"""" + userToLoginPassword + ""\""\n""
                + ""  }\n""
                + ""}"";

            string token = await GenerateToken(host, restUsername, restPassword);

            Console.WriteLine(""Payload: "" + createUserPayload);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var content = new StringContent(createUserPayload, System.Text.Encoding.UTF8, ""application/json"");

                HttpResponseMessage response = await httpClient.PostAsync(host + ""/api/login-tokens"", content);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    string securityToken = jsonObject[""securityToken""].ToString();
                    Console.WriteLine(""SSO Token: "" + securityToken);
                }
                else
                {
                    Console.WriteLine(""Failed to create SSO token. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<string> GenerateToken(string host, string restUsername, string restPassword)
        {
            using (var client = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = restUsername, password = restPassword }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                    return accessToken;
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }
            }

            return null; // Should not reach here due to Environment.Exit
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	userToLogin := ""user1@yellowfin.com.au""
	userToLoginPassword := ""test""

	createUserPayload := fmt.Sprintf(`{
		""signOnUser"": {
			""userName"": ""%s"",
			""password"": ""%s""
		}
	}`, userToLogin, userToLoginPassword)

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	fmt.Println(""Payload:"", createUserPayload)

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", host+""/api/login-tokens"", bytes.NewBuffer([]byte(createUserPayload)))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	var jsonObject map[string]interface{}
	err = json.Unmarshal(body, &jsonObject)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return
	}

	securityToken, ok := jsonObject[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved successfully"")
		return
	}

	fmt.Println(""SSO Token:"", securityToken)
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		fmt.Println(""Error marshaling request body:"", err)
		return """", err
	}

	client := &http.Client{}

	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return """", err
	}

	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	response, err := client.Do(request)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return """", err
	}
	defer response.Body.Close()

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return """", err
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved successfully"")
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const userToLogin = ""user1@yellowfin.com.au"";
    const userToLoginPassword = ""test"";

    const createUserPayload = JSON.stringify({
        signOnUser: {
            userName: userToLogin,
            password: userToLoginPassword
        }
    });

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    console.log(""Payload:"", createUserPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/login-tokens`, {
            method: 'POST',
            headers: headers,
            body: createUserPayload
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const securityToken = jsonResponse.securityToken;

        if (securityToken) {
            console.log(""SSO Token:"", securityToken);
        } else {
            console.error(""Failed to retrieve SSO token"");
        }
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: restUsername,
        password: restPassword
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(""Access Token:"", accessToken);
        } else {
            console.error(""Token not retrieved"");
            return null;
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $userToLogin = ""user1@yellowfin.com.au"";
    $userToLoginPassword = ""test"";

    $createUserPayload = json_encode(array(
        ""signOnUser"" => array(
            ""userName"" => $userToLogin,
            ""password"" => $userToLoginPassword
        )
    ));

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    echo ""Payload: "" . $createUserPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('POST', ""$host/api/login-tokens"", $headers, $createUserPayload);
        $jsonResponse = json_decode($response, true);
        if (isset($jsonResponse['securityToken'])) {
            echo ""SSO Token: "" . $jsonResponse['securityToken'] . ""\n"";
        } else {
            echo ""Failed to retrieve SSO token\n"";
        }
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage() . ""\n"";
    }
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();

    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken . ""\n"";
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time

import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    user_to_login = ""user1@yellowfin.com.au""
    user_to_login_password = ""test""

    create_user_payload = json.dumps({
        ""signOnUser"": {
            ""userName"": user_to_login,
            ""password"": user_to_login_password
        }
    })

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    print(""Payload:"", create_user_payload)

    nonce = random.randint(0, 2 ** 63 - 1)

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.post(host + ""/api/login-tokens"", headers=headers, data=create_user_payload)
        response.raise_for_status()
        json_response = response.json()
        security_token = json_response.get(""securityToken"")
        print(""SSO Token:"", security_token)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")


def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2 ** 63 - 1)

    # Create request body
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    # Create request headers
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    # Send HTTP request
    response = requests.post(host + ""/api/refresh-tokens"", headers=headers, data=request_body)

    # Check response status
    if response.status_code == 200:
        # Parse JSON response
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

if __name__ == ""__main__"":
    main()

Generating an SSO Login Token to access a Tenant

Providing a clientOrgRef will create a token for creating a user session in a tenant. If a clientOrgRef is not supplied, and the user is a member of multiple tenants, then that user will be shown the Client Organization selection screen during the login process. If the user is a member of a single tenant, the user will not be prompted to select a Client Organization during the SSO process.

The clientOrgRef should be populated with the tenant’s Client Organisation reference code, for the user to be logged into that tenant.

{

  "signOnUser": {

    "userName": "admin@yellowfin.com.au",

    "password": "test",

    "clientOrgRef": "CLIENT1"

  }

}

The following examples return the SSO token that can be used to log a user into a Yellowfin tenant without prompting them for the username and password. These examples use the standard paradigm of using a REST Access Token.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a SSO login token for use with a tenant using the Yellowfin REST API
 */
public class CreateSSOTokenWithAccessTokenIntoTenant {
    public static void main(String[] args) throws Exception {

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String userToLogin = ""user1@yellowfin.com.au"";
        String userToLoginPassword = ""test"";
        String clientOrgReference = ""CLIENT1"";

        String createUserPayload = ""{\n""
                + ""  \""signOnUser\"": {\n""
                + ""    \""userName\"": \""""+ userToLogin + ""\"",\n""
                + ""    \""password\"": \""""+ userToLoginPassword + ""\"",\n""
                + ""    \""clientOrgRef\"": \""""+ clientOrgReference + ""\""\n""
                + ""  }\n""
                + ""}"";

        String token = generateToken(host, restUsername, restPassword);

        System.out.println(""Payload: "" + createUserPayload);

        Content c = Request.post(host + ""/api/login-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(createUserPayload, null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement securityToken = jsonObject.get(""securityToken"");

        System.out.println(""SSO Token: "" + securityToken);

    }

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class CreateSSOTokenWithAccessTokenIntoTenant
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string userToLogin = ""user1@yellowfin.com.au"";
            string userToLoginPassword = ""test"";
            string clientOrgReference = ""CLIENT1"";

            string createUserPayload = ""{\n""
                                       + ""  \""signOnUser\"": {\n""
                                       + ""    \""userName\"": \"""" + userToLogin + ""\"",\n""
                                       + ""    \""password\"": \"""" + userToLoginPassword + ""\"",\n""
                                       + ""    \""clientOrgRef\"": \"""" + clientOrgReference + ""\""\n""
                                       + ""  }\n""
                                       + ""}"";

            string token = await GenerateToken(host, restUsername, restPassword);

            Console.WriteLine(""Payload: "" + createUserPayload);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var content = new StringContent(createUserPayload, System.Text.Encoding.UTF8, ""application/json"");

                HttpResponseMessage response = await httpClient.PostAsync(host + ""/api/login-tokens"", content);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    string securityToken = jsonObject[""securityToken""].ToString();
                    Console.WriteLine(""SSO Token: "" + securityToken);
                }
                else
                {
                    Console.WriteLine(""Failed to create SSO token. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<string> GenerateToken(string host, string restUsername, string restPassword)
        {
            using (var client = new HttpClient())
            {
                // Generate nonce
                long nonce = new Random().NextInt64();

                // Create HTTP request
                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = restUsername, password = restPassword }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                // Send request and get response
                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                // Parse JSON response
                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                }
                else
                {
                    Console.WriteLine(""Token not retrieved"");
                    Environment.Exit(-1);
                }

                return accessToken;
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	userToLogin := ""user1@yellowfin.com.au""
	userToLoginPassword := ""test""
	clientOrgReference := ""CLIENT1""

	createUserPayload := `{
  ""signOnUser"": {
    ""userName"": ""` + userToLogin + `"",
    ""password"": ""` + userToLoginPassword + `"",
    ""clientOrgRef"": ""` + clientOrgReference + `""
  }
}`

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	fmt.Println(""Payload:"", createUserPayload)

	nonce := rand.Int63()

	req, err := http.NewRequest(""POST"", host+""/api/login-tokens"", bytes.NewBuffer([]byte(createUserPayload)))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return
	}

	securityToken, ok := jsonResponse[""securityToken""].(string)
	if !ok {
		fmt.Println(""SSO Token not retrieved"")
		return
	}

	fmt.Println(""SSO Token:"", securityToken)
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		fmt.Println(""Error marshaling request body:"", err)
		return """", err
	}

	client := &http.Client{}

	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return """", err
	}

	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	response, err := client.Do(request)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return """", err
	}
	defer response.Body.Close()

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return """", err
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved"")
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const userToLogin = ""user1@yellowfin.com.au"";
    const userToLoginPassword = ""test"";

    const createUserPayload = JSON.stringify({
        signOnUser: {
            userName: userToLogin,
            password: userToLoginPassword,
            clientOrgRef: ""CLIENT1""
        }
    });

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    console.log(""Payload:"", createUserPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/login-tokens`, {
            method: 'POST',
            headers: headers,
            body: createUserPayload
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        const jsonObject = JSON.parse(responseBody);
        const securityToken = jsonObject.securityToken;

        console.log(""SSO Token:"", securityToken);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: restUsername,
        password: restPassword
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
        } else {
            console.log(""Token not retrieved"");
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    // Create user payload
    $createUserPayload = '{
        ""signOnUser"": {
            ""userName"": ""user1@yellowfin.com.au"",
            ""password"": ""test"",
            ""clientOrgRef"": ""CLIENT1""
        }
    }';

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    echo ""Payload: "" . $createUserPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('POST', ""$host/api/login-tokens"", $headers, $createUserPayload);
        $jsonResponse = json_decode($response, true);
        if (isset($jsonResponse['securityToken'])) {
            echo ""SSO Token: "" . $jsonResponse['securityToken'] . ""\n"";
        } else {
            echo ""Failed to retrieve SSO token\n"";
        }
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $restUsername, $restPassword) {
    // Generate nonce
    $nonce = mt_rand();

    // Create request body
    $requestBody = '{
        ""userName"": ""' . $restUsername . '"",
        ""password"": ""' . $restPassword . '""
    }';

    // Create request headers
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    // Send HTTP request
    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    // Parse JSON response
    $jsonResponse = json_decode($response, true);

    // Get access token from response
    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken;

        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main()
?>
Python
import json
import random
import time

import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    user_to_login = ""user1@yellowfin.com.au""
    user_to_login_password = ""test""
    client_org_reference = ""CLIENT1""

    create_user_payload = json.dumps({
        ""signOnUser"": {
            ""userName"": user_to_login,
            ""password"": user_to_login_password,
            ""clientOrgRef"": client_org_reference
        }
    })

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    print(""Payload:"", create_user_payload)

    nonce = random.randint(0, 2 ** 63 - 1)

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.post(host + ""/api/login-tokens"", headers=headers, data=create_user_payload)
        response.raise_for_status()
        json_response = response.json()
        security_token = json_response.get(""securityToken"")
        print(""SSO Token:"", security_token)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")


def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2 ** 63 - 1)

    # Create request body
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    # Create request headers
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    # Send HTTP request
    response = requests.post(host + ""/api/refresh-tokens"", headers=headers, data=request_body)

    # Check response status
    if response.status_code == 200:
        # Parse JSON response
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

if __name__ == ""__main__"":
    main()

Generating an SSO Login Token for targeted entry to a specific page

The loginParameters with the SSO payload allows options to be set for the new session that the token will create.  This can be used to hide and show UI elements, set security parameters, and determine what page the user will land on when they login. This example payload shows that the user's entry will be a dashboard with the supplied dashboard UUID.

{

  "signOnUser": {

    "userName": "user1@yellowfin.com.au",

    "password": "test"

  },

  "loginParameters": [

    "ENTRY=VIEWDASHBOARD",

    "DASHBOARDUUID=5678f33c-c666-4972-8976-9c489accf73b"

  ]

}

The following code examples will create a SSO token with a specified dashboard entry point:

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a targeted SSO login token using the Yellowfin REST API
 */
public class CreateSSOTokenWithAccessTokenToPage {
    public static void main(String[] args) throws Exception {

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String userToLogin = ""user1@yellowfin.com.au"";
        String userToLoginPassword = ""test"";
        String entryDashboardUUID = ""321e5a85-a349-4cfb-b8f4-c9141059a66a"";

        String createUserPayload = ""{\n""
                + ""  \""signOnUser\"": {\n""
                + ""    \""userName\"": \""""+ userToLogin + ""\"",\n""
                + ""    \""password\"": \""""+ userToLoginPassword + ""\""\n""
                + ""  },\n""
                + ""   \""loginParameters\"": [""
                + ""   \""ENTRY=VIEWDASHBOARD\"",""
                + ""\""DASHBOARDUUID="" + entryDashboardUUID + ""\""""
                + "" ] ""
                + ""}"";

        String token = generateToken(host, restUsername, restPassword);

        System.out.println(""Payload: "" + createUserPayload);

        Content c = Request.post(host + ""/api/login-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(createUserPayload, null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement securityToken = jsonObject.get(""securityToken"");

        System.out.println(""SSO Token: "" + securityToken);

    }

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class CreateSSOTokenWithAccessTokenToPage
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string userToLogin = ""user1@yellowfin.com.au"";
            string userToLoginPassword = ""test"";
            string entryDashboardUUID = ""321e5a85-a349-4cfb-b8f4-c9141059a66a"";

            string createUserPayload = ""{\n""
                + ""  \""signOnUser\"": {\n""
                + ""    \""userName\"": \"""" + userToLogin + ""\"",\n""
                + ""    \""password\"": \"""" + userToLoginPassword + ""\""\n""
                + ""  },\n""
                + ""   \""loginParameters\"": [""
                + ""   \""ENTRY=VIEWDASHBOARD\"",""
                + ""\""DASHBOARDUUID="" + entryDashboardUUID + ""\""""
                + "" ] ""
                + ""}"";

            string token = await GenerateToken(host, restUsername, restPassword);

            Console.WriteLine(""Payload: "" + createUserPayload);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var content = new StringContent(createUserPayload, System.Text.Encoding.UTF8, ""application/json"");

                HttpResponseMessage response = await httpClient.PostAsync(host + ""/api/login-tokens"", content);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    string securityToken = jsonObject[""securityToken""].ToString();
                    Console.WriteLine(""SSO Token: "" + securityToken);
                }
                else
                {
                    Console.WriteLine(""Failed to create SSO token. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<string> GenerateToken(string host, string restUsername, string restPassword)
        {
            using (var client = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = restUsername, password = restPassword }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                    return accessToken;
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }
            }

            return null; // Should not reach here due to Environment.Exit
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	userToLogin := ""user1@yellowfin.com.au""
	userToLoginPassword := ""test""
	entryDashboardUUID := ""321e5a85-a349-4cfb-b8f4-c9141059a66a""

	createUserPayload := fmt.Sprintf(`{
		""signOnUser"": {
			""userName"": ""%s"",
			""password"": ""%s"",
			""loginParameters"": [
				""ENTRY=VIEWDASHBOARD"",
				""DASHBOARDUUID=%s""
			]
		}
	}`, userToLogin, userToLoginPassword, entryDashboardUUID)

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	fmt.Println(""Payload:"", createUserPayload)

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", host+""/api/login-tokens"", bytes.NewBuffer([]byte(createUserPayload)))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	var jsonObject map[string]interface{}
	err = json.Unmarshal(body, &jsonObject)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return
	}

	securityToken, ok := jsonObject[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved successfully"")
		return
	}

	fmt.Println(""SSO Token:"", securityToken)
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		fmt.Println(""Error marshaling request body:"", err)
		return """", err
	}

	client := &http.Client{}

	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return """", err
	}

	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	response, err := client.Do(request)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return """", err
	}
	defer response.Body.Close()

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return """", err
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved successfully"")
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const userToLogin = ""user1@yellowfin.com.au"";
    const userToLoginPassword = ""test"";
    const entryDashboardUUID = ""321e5a85-a349-4cfb-b8f4-c9141059a66a"";

    const createUserPayload = JSON.stringify({
        signOnUser: {
            userName: userToLogin,
            password: userToLoginPassword,
            loginParameters: [
                ""ENTRY=VIEWDASHBOARD"",
                `DASHBOARDUUID=${entryDashboardUUID}`
            ]
        }
    });

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    console.log(""Payload:"", createUserPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/login-tokens`, {
            method: 'POST',
            headers: headers,
            body: createUserPayload
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const securityToken = jsonResponse.securityToken;

        if (securityToken) {
            console.log(""SSO Token:"", securityToken);
        } else {
            console.error(""Failed to retrieve SSO token"");
        }
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: restUsername,
        password: restPassword
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(""Access Token:"", accessToken);
        } else {
            console.error(""Token not retrieved"");
            return null;
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $userToLogin = ""user1@yellowfin.com.au"";
    $userToLoginPassword = ""test"";
    $entryDashboardUUID = ""321e5a85-a349-4cfb-b8f4-c9141059a66a"";

    $createUserPayload = json_encode(array(
        ""signOnUser"" => array(
            ""userName"" => $userToLogin,
            ""password"" => $userToLoginPassword,
            ""loginParameters"" => [
                ""ENTRY=VIEWDASHBOARD"",
                ""DASHBOARDUUID=$entryDashboardUUID""
            ]
        )
    ));

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    echo ""Payload: "" . $createUserPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('POST', ""$host/api/login-tokens"", $headers, $createUserPayload);
        $jsonResponse = json_decode($response, true);
        if (isset($jsonResponse['securityToken'])) {
            echo ""SSO Token: "" . $jsonResponse['securityToken'] . ""\n"";
        } else {
            echo ""Failed to retrieve SSO token\n"";
        }
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage() . ""\n"";
    }
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();

    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken . ""\n"";
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time

import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    user_to_login = ""user1@yellowfin.com.au""
    user_to_login_password = ""test""
    entry_dashboard_UUID = ""321e5a85-a349-4cfb-b8f4-c9141059a66a"";

    create_user_payload = json.dumps({
        ""signOnUser"": {
            ""userName"": user_to_login,
            ""password"": user_to_login_password
        },
        ""loginParameters"": [
            ""ENTRY=VIEWDASHBOARD"",
            f'DASHBOARD_UUID={entry_dashboard_UUID}'
        ]
    })

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    print(""Payload:"", create_user_payload)

    nonce = random.randint(0, 2 ** 63 - 1)

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.post(host + ""/api/login-tokens"", headers=headers, data=create_user_payload)
        response.raise_for_status()
        json_response = response.json()
        security_token = json_response.get(""securityToken"")
        print(""SSO Token:"", security_token)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")


def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2 ** 63 - 1)

    # Create request body
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    # Create request headers
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    # Send HTTP request
    response = requests.post(host + ""/api/refresh-tokens"", headers=headers, data=request_body)

    # Check response status
    if response.status_code == 200:
        # Parse JSON response
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

if __name__ == ""__main__"":
    main()

Generating an SSO Login Token without a user password

The loginParameters with the SSO payload allows options to be set for the new session that the token will create.  Enabling noPassword=true, allows for creating a session for a user without their password.

{

  "signOnUser": {

    "userName": "admin@yellowfin.com.au"

  },

  "noPassword": true

}

This can be used in scenarios where user passwords don’t need to be retained. This could involve assigning random UUIDs as passwords when creating new users. If the users are always entering the application via SSO (using the noPassword option), then their real password never needs to be known.

The noPassword option requires the Insecure login flag to be enabled in Yellowfin’s configuration database.

The following code examples illustrates how to create a session token without a user's password:

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a SSO login token without a user's password using the Yellowfin REST API
 */
public class CreateSSOTokenWithAccessTokenNoPassword {
    public static void main(String[] args) throws Exception {

        System.out.println(""SSO Login User without a password"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String userToLogin = ""user1@yellowfin.com.au"";

        String createUserPayload = ""{\n""
                + ""  \""signOnUser\"": {\n""
                + ""    \""userName\"": \""""+ userToLogin + ""\""\n""
                + ""  },\n""
                + "" \""noPassword\"": true \n""
                + ""}"";

        String token = generateToken(host, restUsername, restPassword);

        System.out.println(""Payload: "" + createUserPayload);

        Content c = Request.post(host + ""/api/login-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(createUserPayload, null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement securityToken = jsonObject.get(""securityToken"");

        System.out.println(""SSO Token: "" + securityToken);

    }

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class CreateSSOTokenWithAccessTokenNoPassword
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string userToLogin = ""user1@yellowfin.com.au"";

            string createUserPayload = ""{\n""
                + ""  \""signOnUser\"": {\n""
                + ""    \""userName\"": \"""" + userToLogin + ""\"",\n""
                + ""  },\n""
                + ""  \""noPassword\"": true\n""
                + ""}"";

            string token = await GenerateToken(host, restUsername, restPassword);

            Console.WriteLine(""Payload: "" + createUserPayload);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var content = new StringContent(createUserPayload, System.Text.Encoding.UTF8, ""application/json"");

                HttpResponseMessage response = await httpClient.PostAsync(host + ""/api/login-tokens"", content);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    string securityToken = jsonObject[""securityToken""].ToString();
                    Console.WriteLine(""SSO Token: "" + securityToken);
                }
                else
                {
                    Console.WriteLine(""Failed to create SSO token. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<string> GenerateToken(string host, string restUsername, string restPassword)
        {
            using (var client = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = restUsername, password = restPassword }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                    return accessToken;
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }
            }

            return null; // Should not reach here due to Environment.Exit
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	userToLogin := ""user1@yellowfin.com.au""

	createUserPayload := fmt.Sprintf(`{
		""signOnUser"": {
			""userName"": ""%s""
		},
		""noPassword"": true
	}`, userToLogin)
	
	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	fmt.Println(""Payload:"", createUserPayload)

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", host+""/api/login-tokens"", bytes.NewBuffer([]byte(createUserPayload)))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	var jsonObject map[string]interface{}
	err = json.Unmarshal(body, &jsonObject)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return
	}

	securityToken, ok := jsonObject[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved successfully"")
		return
	}

	fmt.Println(""SSO Token:"", securityToken)
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		fmt.Println(""Error marshaling request body:"", err)
		return """", err
	}

	client := &http.Client{}

	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return """", err
	}

	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	response, err := client.Do(request)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return """", err
	}
	defer response.Body.Close()

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return """", err
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved successfully"")
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const userToLogin = ""user1@yellowfin.com.au"";
    const userToLoginPassword = ""test"";

    const createUserPayload = JSON.stringify({
        signOnUser: {
            userName: userToLogin,
            password: userToLoginPassword
        },
        noPassword: true
    });

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    console.log(""Payload:"", createUserPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/login-tokens`, {
            method: 'POST',
            headers: headers,
            body: createUserPayload
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const securityToken = jsonResponse.securityToken;

        if (securityToken) {
            console.log(""SSO Token:"", securityToken);
        } else {
            console.error(""Failed to retrieve SSO token"");
        }
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: restUsername,
        password: restPassword
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(""Access Token:"", accessToken);
        } else {
            console.error(""Token not retrieved"");
            return null;
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $userToLogin = ""user1@yellowfin.com.au"";
    $userToLoginPassword = ""test"";

    $createUserPayload = json_encode(array(
        ""signOnUser"" => array(
            ""userName"" => $userToLogin,
        ),
        ""noPassword"" => true
    ));

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    echo ""Payload: "" . $createUserPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('POST', ""$host/api/login-tokens"", $headers, $createUserPayload);
        $jsonResponse = json_decode($response, true);
        if (isset($jsonResponse['securityToken'])) {
            echo ""SSO Token: "" . $jsonResponse['securityToken'] . ""\n"";
        } else {
            echo ""Failed to retrieve SSO token\n"";
        }
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage() . ""\n"";
    }
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();

    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken . ""\n"";
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time

import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    user_to_login = ""user1@yellowfin.com.au""

    create_user_payload = json.dumps({
        ""signOnUser"": {
            ""userName"": user_to_login,
        },
        ""noPassword"": True
    })

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    print(""Payload:"", create_user_payload)

    nonce = random.randint(0, 2 ** 63 - 1)

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.post(host + ""/api/login-tokens"", headers=headers, data=create_user_payload)
        response.raise_for_status()
        json_response = response.json()
        security_token = json_response.get(""securityToken"")
        print(""SSO Token:"", security_token)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")


def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2 ** 63 - 1)

    # Create request body
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    # Create request headers
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    # Send HTTP request
    response = requests.post(host + ""/api/refresh-tokens"", headers=headers, data=request_body)

    # Check response status
    if response.status_code == 200:
        # Parse JSON response
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

if __name__ == ""__main__"":
    main()

Perform SSO Logout / Destroy SSO created Session

A session that is created via SSO, can be destroyed using the DELETE /api/login-tokens/{tokenId} end-point, Delete Login Token. When {tokenId} is the tokenId returned by the initial SSO login REST call.

The tokenId is different from the securityToken that is used to initialize the SSO session. The tokenId should be stored by an application that wants the capacity to end the session at a later point in time.

The following code examples illustrate how to destroy an existing session created via SSO Login, with a given tokenId:

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Destroy a SSO session using the Yellowfin REST API
 */
public class DestroySSOSession {
    public static void main(String[] args) throws Exception {

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        // This is a loginTokenId from the initial REST call to receive a securityToken for SSO
        String loginTokenId = ""ac69b491-26cc-c399-7e59-2e441c9e1433"";

        String token = generateToken(host, restUsername, restPassword);

        Content c = Request.delete(host + ""/api/login-tokens/"" + loginTokenId)
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();
        System.out.println(c.toString());

    }

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class DestroySSOSession
    {
        public static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string loginTokenId = ""ac69b491-26cc-c399-7e59-2e441c9e1433"";

            string token = await GenerateToken(host, restUsername, restPassword);

            Console.WriteLine(""Deleting login token: "" + loginTokenId);

            using (var httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                // Create DELETE request
                var request = new HttpRequestMessage(HttpMethod.Delete, host + ""/api/login-tokens/"" + loginTokenId);
                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}, token={token}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.SendAsync(request);

                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to delete login token. Status code: "" + response.StatusCode);
                }
            }
        }

        public static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var httpClient = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                // Create POST request
                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                request.Content = new StringContent(JsonConvert.SerializeObject(new { userName = username, password = password }));
                request.Content.Headers.ContentType = new MediaTypeHeaderValue(""application/json"");

                // Send request and get response
                HttpResponseMessage response = await httpClient.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                // Parse JSON response
                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                }
                else
                {
                    Console.WriteLine(""Token not retrieved"");
                    Environment.Exit(-1);
                }

                return accessToken;
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""
	loginTokenID := ""ac69b491-26cc-c399-7e59-2e441c9e1433""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	fmt.Println(""Deleting login token:"", loginTokenID)

	client := &http.Client{}
	req, err := http.NewRequest(""DELETE"", host+""/api/login-tokens/""+loginTokenID, nil)
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Println(string(body))
}

func generateToken(host, username, password string) (string, error) {
	// Generate nonce
	nonce := rand.Int63()

	// Create request body
	requestBody, err := json.Marshal(map[string]string{
		""userName"": username,
		""password"": password,
	})
	if err != nil {
		fmt.Println(""Error marshaling request body:"", err)
		return """", err
	}

	// Create HTTP client
	client := &http.Client{}

	// Create HTTP request
	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return """", err
	}

	// Add request headers
	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	// Send HTTP request
	response, err := client.Do(request)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return """", err
	}
	defer response.Body.Close()

	// Read response body
	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return """", err
	}

	// Parse JSON response
	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return """", err
	}

	// Get access token from response
	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved"")
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const loginTokenId = ""ac69b491-26cc-c399-7e59-2e441c9e1433"";

    try {
        const token = await generateToken(host, restUsername, restPassword);

        const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

        const headers = {
            'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        };

        const response = await fetch(`${host}/api/login-tokens/${loginTokenId}`, {
            method: 'DELETE',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, username, password) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: username,
        password: password
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
            return accessToken;
        } else {
            throw new Error(""Token not retrieved successfully"");
        }
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $loginTokenId = ""ac69b491-26cc-c399-7e59-2e441c9e1433"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    $nonce = mt_rand();
    $timestamp = intval(microtime(true) * 1000);

    $headers = array(
        'Authorization: YELLOWFIN ts=' . $timestamp . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('DELETE', ""$host/api/login-tokens/$loginTokenId"", $headers);
        echo $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();
    $timestamp = intval(microtime(true) * 1000);

    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . $timestamp . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken;

        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time

import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    login_token_id = ""ac69b491-26cc-c399-7e59-2e441c9e1433""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    nonce = random.randint(0, 2 ** 63 - 1)

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.delete(f'{host}/api/login-tokens/{login_token_id}', headers=headers)
        response.raise_for_status()
        print(response.text)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")

def generate_token(host, username, password):
    nonce = random.randint(0, 2 ** 63 - 1)

    request_body = json.dumps({
        ""userName"": username,
        ""password"": password
    })

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.post(f'{host}/api/refresh-tokens', headers=headers, data=request_body)

    if response.status_code == 200:
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

if __name__ == ""__main__"":
    main()

Using a JWT token for SSO

Yellowfin has an in-built mechanism to consume a JWT token for authentication.  This has less flexibility than using the REST API directly, but it does allow for the implementation of SSO (and on-boarding) to be achieved quite easily.

The JWT token holds all the information to SSO a user into Yellowfin. If a user has already been created, the JWT payload only needs to contain a userId, and SSO can be achieved. The JWT method can also onboard users if they do not exist, however additional information (like name and email address) need to also be provided in the JWT payload so that information can be used to create a new user.

Yellowfin’s JWT implementation supports multiple signing and encryption methods, to ensure that the payload is secure.

JWT can be enabled via the Authentication tab of the Configuration page.  Options here allow for specifying attribute mappings between the JWT payload and the data that Yellowfin needs.

Toggle “JWT Single Sign On” to enable JWT functionality:

Provide mappings from your JWT token to attributes that Yellowfin needs:

If creating a custom JWT token, application code needs to generate the JWT token and sign or encrypt it with a supported algorithm. The website https://jwt.io/ provides a UI for creating JWT tokens manually for testing.

This screenshot from jwt.io shows the payload properties on the right and the resultant JWT token on the left.

The token on the left can be passed to Yellowfin via the below URL. This will act in a similar way to the SSO token, and log the user into Yellowfin, bypassing the username/password prompt.

http://<yellowfin-server-address>/JWTLogin.i4?jwtToken=<jwt-token>

JWT onboarding can also be enabled, and this will create a new user if a user defined within the JWT token does not already exist in Yellowfin (based on the supplied user Id). The JWT Token needs to include attributes required for creating a user if this feature is enabled.

  • No labels