Stream API
Authentication
Most of the API calls that Stream 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 an account, but every single API call afterwards 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.
NOTE: Stream can be configured to only allow X509 Authentication
Authenticating using API-ID and API-KEY
This method of authentication requires you to send your Stream 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://stream.evertrust.fr/api/v1/security/principals/self -H "X-API-ID: administrator" -H "X-API-KEY: Stream" -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 an X509 certificate that has the clientAuth EKU and a Stream X509 account with this certificate's Distinguished Name as identifier. It also requires you to have imported the CA that issued this certificate in Stream 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://stream.evertrust.fr/api/v1/security/principals/self --cert Stream-login-dev-guide.pem --key Stream-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://stream.evertrust.fr/api/v1/security/principals/self -b cookies.txt -H "Accept: application/json"
Handling the CSRF Token
Usually CSRF tokens are used to protect the api calls coming from frontend. A CSRF token is required when all the following are true:
- The request method is not GET, HEAD or OPTIONS.
- The request has one or more Cookie or Authorization headers (like the basic authentication header)
You will receive the following response if a CSRF token is needed but not provided:
<!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>
REST API are usually stateless and should not need cookies. The authentication using API-ID and API-KEY should be used instead of the basic authentication.
Cookies and basic authentication can still be used, in this case you will need to retrieve the token value in the csrf-token cookie and put it in a csrf-token header as well as sending the cookie back.
The following part is an example using curl to see how to retrieve the csrf-token cookies.
First, we make a call to the self api to retrieve the cookies.
$ curl --location 'localhost:9000/api/v1/security/principals/self' --header 'Authorization: Basic YWRtaW5pc3RyYXRvcjpldmVydHJ1c3Q=' -c cookies.txt
Open the cookies.txt file, a csrf-token should be present.
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
#HttpOnly_localhost FALSE / FALSE 1695723782 PLAY_SESSION eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7ImlkZW50aWZpZXIiOiJhZG1pbmlzdHJhdG9yIiwibmFtZSI6Ikhvcml6b24gQWRtaW5pc3RyYXRvciIsImlkcFR5cGUiOiJMb2NhbCIsImlkcE5hbWUiOiJsb2NhbCJ9LCJleHAiOjE2OTU3MjM3ODIsIm5iZiI6MTY5NTcyMjg4MiwiaWF0IjoxNjk1NzIyODgyfQ.6hEmvv2Wh68_k2YN3yENOmzikYZigWCcze64PTO_ooE
localhost FALSE / FALSE 0 csrf-token a7083748beeacdb69d46d27175b357781b5b08c2-1695721881474-92cd447c063b9a12498197d4
Now we try to create a user with curl using cookies without the csrf-token header.
$ curl --location 'localhost:9000/api/v1/security/principalinfos' --header 'Authorization: Basic YWRtaW5pc3RyYXRvcjpldmVydHJ1c3Q=' --data '{"identifier": "test-user","permissions": [{"value": "configuration:*"}]}' -c cookies.txt -b cookies.txt
The Unauthorized html page appears.
To validate the csrf token, we need to send the request with a csrf-token header containing the token value in the csrf-token cookie.
$ curl --location 'localhost:9000/api/v1/security/principalinfos' --header 'Authorization: Basic YWRtaW5pc3RyYXRvcjpldmVydHJ1c3Q=' --header 'Content-Type: application/json' --header 'csrf-token: a7083748beeacdb69d46d27175b357781b5b08c2-1695721881474-92cd447c063b9a12498197d4' --data '{"identifier": "test-user","permissions": [{"value": "configuration:*"}]}' -c cookies.txt -b cookies.txt
The API should not return the Unauthorized html page.