Authentication (legacy)
This authentication method is deprecated and should only be used in Adaxes 2025.1 and below. In newer versions, you can create access tokens via the New-AdmAccountToken cmdlet.
The authentication process with Adaxes REST API consists of two HTTP requests that must be executed in the following order:
- Create authentication session.
- Obtain access token.
An authentication session is required only to issue a token. Once a token is obtained, you can use it to perform operations via the API by adding the token value in the Adm-Authorization header to each request.
Create authentication session
This request creates an authentication session for a specific user account. The account must be located in a domain managed by Adaxes.
POST ~/api/authSessions/create
Operations that you can perform via REST API are determined by the security roles assigned to the authenticated user.
Request headers
-
Name
-
Required
-
Description
-
Content-Type
-
True
-
Use application/json as the value of this header.
Request body
The request body is a JSON object with the following data structure:
{
"username": "<username>",
"password": "<password>"
}
username string
User's logon name in one of the following formats: username@domain.com or DOMAIN\username.
password string
User's password.
Responses
If successful, returns 200 OK status code and an AuthSession object in the response body. Otherwise, returns one of the common HTTP error codes and an error description in the response body.
AuthSession is a JSON representation of an authentication session with the following data structure:
{
"sessionId": "<sessionID>",
"expiresAtUtc": "<expiresAtUtc>"
}
sessionId string
The identifier of the authentication session.
Take note of the sessionId value from your response and keep it secret. The session identifier is required to issue a access token.
expiresAtUtc datetime
Specifies when the session expires. Once a session expires, its identifier can no longer be used to issue new tokens. All existing tokens will remain valid until they are destroyed or expire.
You can change the maximum session lifetime. For information on how to do this, see Change session lifetime.
Examples
Create an authentication session
The following code sample creates an authentication session.
Request
- PowerShell
-
$baseUrl = "https://host.example.com/restApi" $endpoint = "/api/authSessions/create" # Request parameters $requestUrl = $baseUrl + $endpoint $requestBody = ConvertTo-Json @{ "username" = "administrator@example.com"; "password" = "MyPassword" } # Make request Invoke-RestMethod -Method POST -Uri $requestUrl ` -Body $requestBody -ContentType "application/json" - C#
-
using System; using System.Text; using System.Net.Http; using System.Threading.Tasks; class Program { static async Task Main() { const string baseUrl = "https://host.example.com/restApi"; const string endpoint = "/api/authSessions/create"; // Create JSON request body string jsonRequest = @" { ""username"": ""administrator@example.com"", ""password"": ""MyPassword"" }"; StringContent requestBody = new(jsonRequest, Encoding.UTF8, "application/json"); // Initialize HTTP client using HttpClient client = new(); // Make request HttpResponseMessage response = await client.PostAsync( baseUrl + endpoint, requestBody); string responseBody = response.Content.ReadAsStringAsync().Result; Console.WriteLine(responseBody); } } - cURL
-
curl --request POST 'https://host.example.com/restApi/api/authSessions/create' \ --header 'Content-Type: application/json' \ --data-raw '{ "username": "administrator@example.com", "password": "MyPassword" }' - node.js
-
async function createAuthSession() { // Request parameters const baseUrl = "https://host.example.com/restapi"; const endpoint = "/api/authSessions/create"; const requestPath = `${baseUrl}${endpoint}`; // Create JSON request body const requestBody = { username: "administrator@example.com", password: "MyPassword" }; // Make request const response = await fetch(requestPath, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }); if (!response.ok) { throw new Error(`Request failed with status ${response.status}`); } const result = await response.json(); console.log(result); } createAuthSession(); - Python
-
import requests import json baseUrl = "https://host.example.com/restApi" endpoint = "/api/authSessions/create" # Request parameters requestUrl = baseUrl + endpoint requestBody = { "username": "administrator@example.com", "password": "MyPassword" } # Make request request = requests.post(requestUrl, json=requestBody) response = json.loads(request.content) print(response)
Response
HTTP Status code: 200 OK
Response body:
{
"sessionId": "LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5",
"expiresAtUtc": "2020-07-30T15:41:10.3730467Z"
}
Obtain access token
This request uses an existing authentication session to obtain an access token.
POST ~/api/auth
Request headers
-
Name
-
Required
-
Description
-
Content-Type
-
True
-
Use application/json as the value of this header.
Request body
The request body is a JSON object with the following data structure:
{
"sessionId": "<sessionId>"
}
sessionId string
The identifier of an existing authentication session.
In Adaxes 2023.2 and below, the request body must also include the type attribute with the value of 0.
Example
{
"sessionId": "<sessionId>",
"type": 0
}
Responses
If successful, returns 200 OK status code and an AuthTicketInfo object in the response body. Otherwise, returns one of the common HTTP error codes and an error description in the response body.
AuthTicketInfo is a JSON representation of an authentication ticket with the following data structure:
{
"id": "<id>",
"token": "<token>",
"sid": "<SID>",
"expiresAtUtc": "<expiresAtUtc>",
"applications": [
"<REST API>"
]
}
id string
The ticket identifier.
token string
The access token. Specify it as the value of the Adm-Authorization header in all further requests.
Take note of the token value from your response and keep it secret until the ticket expires or is destroyed. Anyone in possession of a valid access token can perform operations via the API.
sid string
The Security identifier (SID) of the user who was issued the authentication ticket.
expiresAtUtc datetime
Specifies when the access token expires. Once a token expires, any requests with its value in the Adm-Authorization header will be considered as unauthorized and will be rejected by the server.
You can change the maximum token lifetime. For information on how to do this, see Change token lifetime.
applications string array
Always contains a single element that equals REST API. Specifies that the token grants access to the REST API.
Examples
Obtain access token
The following code sample obtains an access token.
Request
- PowerShell
-
$baseUrl = "https://host.example.com/restApi" $endpoint = "/api/auth" # Request parameters $requestUrl = $baseUrl + $endpoint $requestBody = ConvertTo-Json @{ "sessionId" = "LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5" } # Make request Invoke-RestMethod -Method POST -Uri $requestUrl ` -Body $requestBody -ContentType "application/json" - C#
-
using System; using System.Text; using System.Net.Http; using System.Threading.Tasks; class Program { static async Task Main() { const string baseUrl = "https://host.example.com/restApi"; const string endpoint = "/api/auth"; // Create JSON request body string jsonRequest = @" { ""sessionId"": ""LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5"" }"; StringContent requestBody = new(jsonRequest, Encoding.UTF8, "application/json"); // Initialize HTTP client using HttpClient client = new(); // Make request HttpResponseMessage response = await client.PostAsync( baseUrl + endpoint, requestBody); string responseBody = response.Content.ReadAsStringAsync().Result; Console.WriteLine(responseBody); } } - cURL
-
curl --request POST 'https://host.example.com/restApi/api/auth' \ --header 'Content-Type: application/json' \ --data-raw '{ "sessionId": "LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5" }' - node.js
-
async function authenticateSession() { // Request parameters const baseUrl = "https://host.example.com/restapi"; const endpoint = "/api/auth"; const requestPath = `${baseUrl}${endpoint}`; // Create JSON request body const requestBody = { sessionId: "LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5" }; // Make request const response = await fetch(requestPath, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }); if (!response.ok) { throw new Error(`Request failed with status ${response.status}`); } const result = await response.json(); console.log(result); } authenticateSession(); - Python
-
import requests import json baseUrl = "https://host.example.com/restApi" endpoint = "/api/auth" # Request parameters requestUrl = baseUrl + endpoint requestBody = { "sessionId": "LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5" } # Make request request = requests.post(requestUrl, json=requestBody) response = json.loads(request.content) print(response)
Response
HTTP Status code: 200 OK
Response body:
{
"id": "5PG_xHGLU7YhKI5vb4GCvvNHs8VaCPvuHVIlj",
"token": YOUR-ACCESS-TOKEN,
"sid": "S-1-5-21-3656734-1720699-187516-1186",
"expiresAtUtc": "2020-08-03T10:26:22.898414Z",
"applications": [
"<REST API>"
]
}
Renew access token
You can renew an access token by making this request. The previous token will still be valid until its expiration date or until destroyed.
PATCH ~/api/auth?<parameters>
Token renewal does not require an existing authentication session.
Query parameters
Request headers
-
Name
-
Required
-
Description
-
Adm-Authorization
-
True
-
Specify a valid access token.
Responses
If successful, returns 200 OK status code and an AuthTicketInfo object with the new access token and its expiration date in the response body. Otherwise, returns one of the common HTTP error codes and an error description in the response body.
Examples
Renew access token
The following code sample renews the specified access token.
Request
- PowerShell
-
Add-Type -AssemblyName System.Web $baseUrl = "https://host.example.com/restApi" $endpoint = "/api/auth" # Request parameters $queryParams = "?token=" + [System.Web.HttpUtility]::UrlEncode(YOUR-ACCESS-TOKEN) $requestUrl = $baseUrl + $endpoint + $queryParams $requestHeaders = @{"Adm-Authorization" = YOUR-ACCESS-TOKEN} # Make request Invoke-RestMethod -Method PATCH -Headers $requestHeaders -Uri $requestUrl - C#
-
using System; using System.Web; using System.Net.Http; using System.Threading.Tasks; class Program { static async Task Main() { const string baseUrl = "https://host.example.com/restApi"; const string endpoint = "/api/auth"; // Request parameters string encodedToken = HttpUtility.UrlEncode(YOUR-ACCESS-TOKEN); UriBuilder requestUrl = new() { Host = baseUrl + endpoint, Query = $"?token={encodedToken}" }; // Initialize HTTP client using HttpClient client = new(); client.DefaultRequestHeaders.Add("Adm-Authorization", YOUR-ACCESS-TOKEN); // Make request HttpResponseMessage response = await client.PatchAsync( requestUrl.ToString(), null); string responseBody = response.Content.ReadAsStringAsync().Result; Console.WriteLine(responseBody); } } - cURL
-
curl --header 'Adm-Authorization: YOUR-ACCESS-TOKEN' \ --get -X PATCH 'https://host.example.com/restApi/api/auth' \ --data-urlencode 'token=YOUR-ACCESS-TOKEN' - node.js
-
async function refreshAuthToken() { // Request parameters const encodedToken = encodeURIComponent("YOUR-ACCESS-TOKEN"); const baseUrl = "https://host.example.com/restapi"; const endpoint = "/api/auth"; const requestParams = `?token=${encodedToken}`; const requestPath = `${baseUrl}${endpoint}${requestParams}`; // Make request const response = await fetch(requestPath, { method: "PATCH", headers: { "Adm-Authorization": "YOUR-ACCESS-TOKEN" } }); if (!response.ok) { throw new Error(`Request failed with status ${response.status}`); } const result = await response.json(); console.log(result); } refreshAuthToken(); - Python
-
import requests import json baseUrl = "https://host.example.com/restApi" endpoint = "/api/auth" # Request parameters requestUrl = baseUrl + endpoint requestHeaders = {"Adm-Authorization": YOUR-ACCESS-TOKEN} queryParams = {"token": YOUR-ACCESS-TOKEN} # Make request request = requests.patch(requestUrl, headers=requestHeaders, params=queryParams) response = json.loads(request.content) print(response)
Response
HTTP Status code: 200 OK
Response body:
{
"id": "5PG_xHGLU7YhKI5vb4GCvvNHs8VaCPvuHVIlj",
"token": "FU3Y9Jyz1Hf2bc7....w7lQvxjJHP9prwuDfCVd4K",
"sid": "S-1-5-21-3656734-1720699-187516-1186",
"expiresAtUtc": "2020-08-03T14:22:16.831510Z",
"applications": [
"<REST API>"
]
}
Terminate authentication session
You can terminate an existing authentication session manually before its expiration by making this request.
DELETE ~/api/authSessions?<parameters>
Query parameters
-
Name
-
Required
-
Type
-
Description
-
id -
True
-
string
-
The identifier of the authentication session which should be terminated.
Responses
Always returns 204 No Content status code.
Examples
Terminate authentication session
The following code sample terminates the specified authentication session.
Request
- PowerShell
-
$baseUrl = "https://host.example.com/restApi" $endpoint = "/api/authSessions" # Request parameters $queryParams = "?id=LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5" $requestUrl = $baseUrl + $endpoint + $queryParams # Make request Invoke-RestMethod -Method DELETE -Uri $requestUrl - C#
-
using System; using System.Net.Http; using System.Threading.Tasks; class Program { static async Task Main() { const string baseUrl = "https://host.example.com/restApi"; const string endpoint = "/api/authSessions"; // Request parameters const string sessionId = "LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5"; string requestParams = $"?id={sessionId}"; // Initialize HTTP client using HttpClient client = new(); // Make request HttpResponseMessage response = await client.DeleteAsync( baseUrl + endpoint + requestParams); string responseBody = response.Content.ReadAsStringAsync().Result; Console.WriteLine(responseBody); } } - cURL
-
curl --get -X DELETE 'https://host.example.com/restApi/api/authSessions' \ --data-urlencode 'id=LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5' - node.js
-
async function deleteAuthSession() { // Request parameters const sessionId = encodeURIComponent("LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5"); const baseUrl = "https://host.example.com/restapi"; const endpoint = "/api/authSessions"; const requestParams = `?id=${sessionId}`; const requestPath = `${baseUrl}${endpoint}${requestParams}`; // Make request const response = await fetch(requestPath, { method: "DELETE", headers: { "Adm-Authorization": "YOUR-ACCESS-TOKEN" } }); if (!response.ok) { throw new Error(`Request failed with status ${response.status}`); } const result = await response.json(); console.log(result); } deleteAuthSession(); - Python
-
import requests import json baseUrl = "https://host.example.com/restApi" endpoint = "/api/authSessions" # Request parameters requestUrl = baseUrl + endpoint queryParams = {"id": "LBxsm-yOBDNSxwT6o_DLAOf9ocVRtW5"} # Make request request = requests.delete(requestUrl, params=queryParams)
Response
HTTP Status code: 200 OK
Destroy access token
You can destroy an existing access token manually before its expiration by making this request.
DELETE ~/api/auth?<parameters>
Query parameters
-
Name
-
Required
-
Type
-
Description
-
token -
True
-
string
-
The identifier of the access token which should be destroyed.
Request headers
-
Name
-
Required
-
Description
-
Adm-Authorization
-
True
-
Specify a valid access token.
Responses
Always returns 204 No Content status code.
Examples
Destroy access token
The following code sample destroys the specified access token.
Request
- PowerShell
-
Add-Type -AssemblyName System.Web $baseUrl = "https://host.example.com/restApi" $endpoint = "/api/auth" # Request parameters $queryParams = "?token=" + [System.Web.HttpUtility]::UrlEncode(YOUR-ACCESS-TOKEN) $requestUrl = $baseUrl + $endpoint + $queryParams $requestHeaders = @{"Adm-Authorization" = YOUR-ACCESS-TOKEN} # Make request Invoke-RestMethod -Method DELETE -Headers $requestHeaders -Uri $requestUrl - C#
-
using System; using System.Web; using System.Net.Http; using System.Threading.Tasks; class Program { static async Task Main() { const string baseUrl = "https://host.example.com"; const string endpoint = "/restApi/api/auth"; // Request parameters string encodedToken = HttpUtility.UrlEncode(YOUR-ACCESS-TOKEN); UriBuilder requestUrl = new() { Host = baseUrl + endpoint, Query = $"?token={encodedToken}" }; // Initialize HTTP client using HttpClient client = new(); client.DefaultRequestHeaders.Add("Adm-Authorization", YOUR-ACCESS-TOKEN); // Make request HttpResponseMessage response = await client.DeleteAsync(requestUrl.ToString()); string responseBody = response.Content.ReadAsStringAsync().Result; Console.WriteLine(responseBody); } } - cURL
-
curl --header 'Adm-Authorization: YOUR-ACCESS-TOKEN' \ --get -X DELETE 'https://host.example.com/restApi/api/auth' \ --data-urlencode 'token=YOUR-ACCESS-TOKEN' - node.js
-
async function revokeAuthToken() { // Request parameters const encodedToken = encodeURIComponent("YOUR-ACCESS-TOKEN"); const baseUrl = "https://host.example.com/restapi"; const endpoint = "/api/auth"; const requestParams = `?token=${encodedToken}`; const requestPath = `${baseUrl}${endpoint}${requestParams}`; // Make request const response = await fetch(requestPath, { method: "DELETE", headers: { "Adm-Authorization": "YOUR-ACCESS-TOKEN" } }); if (!response.ok) { throw new Error(`Request failed with status ${response.status}`); } const result = await response.json(); console.log(result); } revokeAuthToken(); - Python
-
import requests import json baseUrl = "https://host.example.com/restApi" endpoint = "/api/auth" # Request parameters requestUrl = baseUrl + endpoint requestHeaders = {"Adm-Authorization": YOUR-ACCESS-TOKEN} queryParams = {"token": YOUR-ACCESS-TOKEN} # Make request request = requests.delete(requestUrl, headers=requestHeaders, params=queryParams)
Response
HTTP Status code: 204 No Content
Full authentication process
The following code sample demonstrates the full authentication process. It authenticates a user to REST API, and then invalidates the authentication session and access token.
- PowerShell
-
$baseUrl = "https://host.example.com/restApi" $username = "administrator@example.com" $password = "MyPassword" # Session request parameters $requestUrl = $baseUrl + "/api/authSessions/create" $requestBody = ConvertTo-Json @{ "username" = $username; "password" = $password } # Create session $session = Invoke-RestMethod -Method POST -Uri $requestUrl ` -Body $requestBody -ContentType "application/json" # Get session ID $sessionId = $session.sessionId # Access token request parameters $requestUrl = $baseUrl + "/api/auth" $requestBody = ConvertTo-Json @{ "sessionId" = $sessionId } # Obtain token $authTicketInfo = Invoke-RestMethod -Method POST -Uri $requestUrl ` -Body $requestBody -ContentType "application/json" $token = $authTicketInfo.token # Insert your requests here # Optionally: renew token # Renew token parameters $queryParams = "?token=" + [System.Web.HttpUtility]::UrlEncode($token) $requestUrl = $baseUrl + "/api/auth" + $queryParams $requestHeaders = @{"Adm-Authorization" = $token} # Renew token $authTicketInfo = Invoke-RestMethod -Method PATCH -Headers $requestHeaders ` -Uri $requestUrl $newExpirationDate = $authTicketInfo.expiresAtUtc $token = $authTicketInfo.token # Session and token will expire automatically # Optionally: terminate session and destroy token manually # Terminate session parameters $requestUrl = $baseUrl + "/api/authSessions?id=$sessionId" # Terminate session Invoke-RestMethod -Method DELETE -Uri $requestUrl # Destroy token parameters $queryParams = "?token=" + [System.Web.HttpUtility]::UrlEncode($token) $requestUrl = $baseUrl + "/api/auth" + $queryParams $requestHeaders = @{"Adm-Authorization" = $token} # Destroy token Invoke-RestMethod -Method DELETE -Headers $requestHeaders -Uri $requestUrl - C#
-
using System.Web; using System.Text; using System.Text.Json; class Program { private const string url = "https://host.example.com/restApi"; private static HttpClient client = new(); static async Task Main() { // Get credentials string? username = Console.ReadLine(); string? password = Console.ReadLine(); string sessionId = null; string token = null; try { string jsonBody = $@" {{ 'username': ""{username}"", 'password': ""{password}"" }}"; StringContent requestBody = new(jsonBody, Encoding.UTF8, "application/json"); // Get the session identifier. HttpResponseMessage response = await client.PostAsync( $"{url}/api/authSessions/create", requestBody); string responseBody = response.Content.ReadAsStringAsync().Result; sessionId = GetJsonElement(responseBody, "sessionId"); jsonBody = $@" {{ 'sessionId': ""{sessionId}"" }}"; requestBody = new(jsonBody, Encoding.UTF8, "application/json"); // Get an access token. response = await client.PostAsync($"{url}/api/auth", requestBody); responseBody = response.Content.ReadAsStringAsync().Result; token = GetJsonElement(responseBody, "token"); // Attach the access token to the HTTP client. client.DefaultRequestHeaders.Add("Adm-Authorization", token); // Renew the token every 29 minutes before it expires. using Timer timer = new( new TimerCallback(RenewToken), token, TimeSpan.Zero, TimeSpan.FromMinutes(29)); // Insert your code here } finally { // Terminate the authentication session and destroy the access token. if (sessionId is not null) await client.DeleteAsync($"{url}/api/auth?id={sessionId}"); if (token is not null) await client.DeleteAsync($"{url}/api/auth?token={token}"); // Release resources client.Dispose(); } } /// <summary> /// Returns the specified JSON element as a string. /// </summary> private static string GetJsonElement(string text, string elementName) { using JsonDocument doc = JsonDocument.Parse(text); return doc.RootElement.GetProperty(elementName).ToString(); } /// <summary> /// Renews an access token. /// </summary> private static void RenewToken(object? token) { if (token is not null) { string requestParams = $"?token={HttpUtility.UrlEncode(token.ToString())}"; client.PatchAsync($"{url}/api/auth{requestParams}", null).GetAwaiter().GetResult(); } } }
Alternative approach
The value of the access token contains encoded information that facilitates load balancing between Adaxes services that share common configuration. As a result, the token length can easily exceed 400 characters. Some client applications that send HTTP requests have a limitation on the header length, so it might not be possible to specify the token as the value of the Adm-Authorization header.
If this is the case, you can specify the identifier of the authentication ticket (AuthTicketInfo.id) as the value of the Adm-Authorization header instead. Such requests will be considered authorized only on one Adaxes service instance – the one where the ticket was issued.
If you have multiple Adaxes service instances that share common configuration and have to use this alternative method, you need to force all further REST API requests to be processed by the same Adaxes service. To do this, capture the value of the Adm-Service response header, and add it as a request header to each subsequent request.
The following code sample creates an authentication session, obtains the authentication ticket identifier and the value of the Adm-Service header, and then uses these values to send a request to retrieve a user.
- PowerShell
-
$baseUrl = "https://host.example.com/restApi" $username = "administrator@example.com" $password = "MyPassword" # Create authentication session. $requestUrl = $baseUrl + "/api/authSessions/create" $requestBody = ConvertTo-Json @{ "username" = $username; "password" = $password } $session = Invoke-RestMethod -Method POST -Uri $requestUrl ` -Body $requestBody -ContentType "application/json" # Get session ID. $sessionId = $session.sessionId # Obtain authentication ticket. $requestUrl = $baseUrl + "/api/auth" $requestBody = ConvertTo-Json @{ "sessionId" = $sessionId } $authTicketInfo = Invoke-WebRequest -Method POST -Uri $requestUrl ` -Body $requestBody -ContentType "application/json" # Get response header and ticket identifier. $serviceHeader = $authTicketInfo.Headers.'Adm-Service' $ticketId = ($authTicketInfo.Content | ConvertFrom-Json).id # Once you have the ticket identifier and the Adm-Service header, # use these values in subsequent requests. For example, to get a user: # Specify request parameters. $userIdentifier = "CN=John Dowson,CN=Users,DC=example,DC=com" $requestUrl = $baseUrl + "/api/directoryObjects?directoryObject=$userIdentifier" $requestHeaders = @{ "Adm-Authorization" = $ticketId; "Adm-Service" = $serviceHeader } # Make request Invoke-RestMethod -Method GET -Headers $requestHeaders -Uri $requestUrl - C#
-
using System.Web; using System.Text; using System.Text.Json; class Program { private const string url = "https://host.example.com/restApi"; private static HttpClient client = new(); static async Task Main() { // Get credentials string? username = Console.ReadLine(); string? password = Console.ReadLine(); string sessionId = null; string ticketId = null; try { string jsonBody = $@" {{ 'username': ""{username}"", 'password': ""{password}"" }}"; StringContent requestBody = new(jsonBody, Encoding.UTF8, "application/json"); // Get the session identifier. HttpResponseMessage response = await client.PostAsync( $"{url}/api/authSessions/create", requestBody); string responseBody = response.Content.ReadAsStringAsync().Result; sessionId = GetJsonElement(responseBody, "sessionId"); jsonBody = $@" {{ 'sessionId': ""{sessionId}"" }}"; requestBody = new(jsonBody, Encoding.UTF8, "application/json"); // Get the authentication ticket identifier // and the Adm-Service header. response = await client.PostAsync($"{url}/api/auth", requestBody); IEnumerable<string> headerValues = response.Headers.GetValues("Adm-Service"); responseBody = response.Content.ReadAsStringAsync().Result; ticketId = GetJsonElement(responseBody, "id"); // Attach the ticket identifier to the HTTP client. client.DefaultRequestHeaders.Add("Adm-Authorization", ticketId); // Renew the ticket every 29 minutes before it expires. using Timer timer = new( new TimerCallback(RenewTicket), ticketId, TimeSpan.Zero, TimeSpan.FromMinutes(29)); // Send all subsequent requests to the same Adaxes service. client.DefaultRequestHeaders.Add("Adm-Service", headerValues.Single()); // Insert your code here } finally { // Terminate the authentication session and destroy the ticket. if (sessionId is not null) await client.DeleteAsync($"{url}/api/auth?id={sessionId}"); if (ticketId is not null) await client.DeleteAsync($"{url}/api/auth?token={ticketId}"); // Release resources client.Dispose(); } } /// <summary> /// Returns the specified JSON element as a string. /// </summary> private static string GetJsonElement(string text, string elementName) { using JsonDocument doc = JsonDocument.Parse(text); return doc.RootElement.GetProperty(elementName).ToString(); } /// <summary> /// Renews an authentication ticket. /// </summary> private static void RenewTicket(object? ticketId) { if (ticketId is not null) { string requestParams = $"?token={HttpUtility.UrlEncode(ticketId.ToString())}"; client.PatchAsync($"{url}/api/auth{requestParams}", null).GetAwaiter().GetResult(); } } }