Horizon API
Authentication
Most of the API calls that Horizon uses require you to be authenticated to the API. The first authentication can either be done through the use of an X509 certificate or using credentials of a local account, but every single API call afterward will need to bear the authentication information nonetheless. Regardless of the chosen authentication method, the authorization used must have sufficient permissions to perform the desired operation.
Authenticating using API-ID and API-KEY
This method of authentication requires you to send your Horizon local account credentials as HTTP headers. To check whether the credentials are correct, you can perform a GET request on /api/v1/security/principals/self and check for the response status :
$ curl https://horizon.evertrust.fr/api/v1/security/principals/self -H "X-API-ID: administrator" -H "X-API-KEY: horizon" -H "Accept: application/json"
Possible responses are:
HTTP Response code | Additional information |
---|---|
200 | The login information were correct |
401 | Authentication error, please refer to the response body for more details |
Authenticating using an X509 certificate
This method of authentication requires to have a created authorization based on an X509 certificate that has the clientAuth EKU. It also requires you to have imported the CA that issued this certificate in Horizon and turning on the "Trusted for client authentication" switch on that CA. You must then present the certificate on the request you are performing.
To check for the authentication, you can perform a GET request on /api/v1/security/principals/self :
$ curl https://horizon.evertrust.fr/api/v1/security/principals/self --cert horizon-login-dev-guide.pem --key horizon-login-dev-guide.key -H "Accept: application/json"
Possible responses are:
HTTP Response code | Additional information |
---|---|
200 | The login information were correct |
401 | Authentication error, please refer to the response body for more details |
Handling next authentications using the Play Session
Once the first authentication is done, the API generates a cookie called "PLAY_SESSION". This cookie holds the authentication information that was used to make the first login (using either previously mentioned method). To save its value for later use, just append the -c cookies.txt to either of the previous curl requests. Instead of using the credentials as headers or passing the certificate at each API call, you can use the cookie :
$ curl https://horizon.evertrust.fr/api/v1/security/principals/self -b cookies.txt -H "Accept: application/json"
Handling CSRF Token
Our api are used by a frontend and require a CSRF protection. A CSRF token validation is needed when all of the following are true:
- The request method is not GET, HEAD or OPTIONS.
- The request has one or more Cookie or Authorization headers.
Receiving the following response probably means that your request has failed the CSRF token validation:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Unauthorized</title>
<style type="text/css">
html, body, pre {
margin: 0;
padding: 0;
font-family: Monaco, 'Lucida Console', monospace;
background: #ECECEC;
}
h1 {
margin: 0;
background: #333;
padding: 20px 45px;
color: #fff;
text-shadow: 1px 1px 1px rgba(0,0,0,.3);
border-bottom: 1px solid #111;
font-size: 28px;
}
p#detail {
margin: 0;
padding: 15px 45px;
background: #888;
border-top: 4px solid #666;
color: #111;
text-shadow: 1px 1px 1px rgba(255,255,255,.3);
font-size: 14px;
border-bottom: 1px solid #333;
}
</style>
</head>
<body>
<h1>Unauthorized</h1>
<p id="detail">
You must be authenticated to access this page.
</p>
</body>
</html>
To avoid the CSRF token validation in api usage:
- Authentication using API-ID and API-KEY headers should be prioritized as http basic authentication results in the creation of an Authorization header.
- Avoid the use of cookies as api usage does not require them.
If you cannot avoid those cases, the following procedure explains how to handle the CSRF token validation.
First you will have to retrieve a valid cookie CSRF token from the server.
$ curl https://horizon.evertrust.fr/api/v1/security/principals/self --header 'X-API-ID:administrator' --header 'X-API-KEY:horizon' -c cookies.txt
Once done the file cookies.txt should have two entries:
- A play session
- A CSRF token:
localhost FALSE / FALSE 0 csrf-token 456aa18162e8736047dbd878617283aa361cd83e-1708941483170-da503a15304a666a96748f5d
localhost FALSE / FALSE 1708942383 PLAY_SESSION eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7ImlkZW50aWZpZXIiOiJhZG1pbmlzdHJhdG9yIiwibmFtZSI6Ikhvcml6b24gQWRtaW5pc3RyYXRvciIsImlkcFR5cGUiOiJMb2NhbCIsImlkcE5hbWUiOiJsb2NhbCJ9LCJleHAiOjE3MDg5NDIzODMsIm5iZiI6MTcwODk0MTQ4MywiaWF0IjoxNzA4OTQxNDgzfQ.79xRjdGhaVv_5mM8bpkLgcL78QCEWu08zgthP_dt9Pc
To successfully authenticate to the server, both the csrf-token cookie and a csrf-token header containing the cookie content should be defined.
Sending a POST request using cookies without the csrf-token header will result in the forbidden html page:
curl --location 'localhost:9000/api/v1/certificate/labels' \
--header 'X-API-ID: administrator' \
--header 'X-API-KEY: evertrust' \
--header 'Content-Type: application/json' \
-b cookies.txt \
--data '{
"name": "NEW_LABEL",
"displayName" : [],
"description": []
}'
A valid authentication also copies the content in the csrf-token header:
curl --location 'localhost:9000/api/v1/certificate/labels' \
--header 'X-API-ID: administrator' \
--header 'X-API-KEY: evertrust' \
--header 'csrf-token: 456aa18162e8736047dbd878617283aa361cd83e-1708941483170-da503a15304a666a96748f5d' \
--header 'Content-Type: application/json' \
--data '{
"name": "NEW_LABEL",
"regex": null,
"displayName" : [],
"description": []
}'