Token Authentication

For authenticating users we use JWT token authentication, meaning that the user of the REST API must send a bearer token in the header whenever making requests to endpoints that require authentication.

Example of Use

For instance consider a login request:

1
curl -X POST "http://localhost:5000/v1/Account/login" -H "accept: text/plain" -H "Content-Type: application/json-patch+json" -d "{ \"username\": \"<yourUserName>\", \"password\": \"<youPassword>\"}"

This login request will return a token.

One can then set the token in the authentication header: Authorization: Bearer <token>

And thus a request to get all department names would look like this:

1
curl -X GET "http://localhost:5000/v1/Department" -H "accept: text/plain" -H "Authorization: Bearer <token>"

For examples of how to do this in swagger see the README file at the web-api repository.

How is JWT configured in GIRAF

The configuration is loaded in the Startup.cs class:

1
2
3
4
5
6
public void ConfigureServices(IServiceCollection services)
{
    //commented out for brevity...
    services.Configure<JwtConfig>(Configuration.GetSection("Jwt"));
    //commented out for brevity...
}

Thus the settings are configured in appsettings.json in the section called Jwt:

1
2
3
4
5
6
7
8
9
{
    ...
    "Jwt": {
        "JwtKey": "<30 symbol jwtkey>",
        "JwtIssuer": "AAU",
        "JwtExpireDays": 30
    }
    ...
}

What is a JWT

JSON Web Token is an authentication token, which actually contains user information, as opposed to API keys. Traditionally, API keys can be a GUID or a nonsense string, which is really a primary key in a database, when supplied in the header of an HTTP request, the backend will then make an appropriate lookup across tables or with its authentication service to ascertain the rights of the user in question, if any. A JWT works differently: It actually contains serialized information about the user, and their access rights, this has the advantage of saving the service from database lookups, to obtain the information. It also contains a timestamp, by which the service can determine whether it is still valid.

Comparison between classic API Key usage, and JWT

API Key Flow JWT Flow
Login Request
(not necessary for a classic API key) 1. Login request is made by the client
2. The Server retrieves the users permissions from the database
3. The Server generates a JSON object containing the users permissions signs it and serializes it
4. The client receives the token
General Requests
1. The client makes a request, supplying the key in its header 1. The client makes a request, supplying the JWT in the header
2. The server looks up the key in the database and checks the permissions 2. The server performs the request
3. The server performs the requested action 3. The client receives the response
4. The client receives the response

So while it requires an initial login to use the JWT, we can see that it saves the server a database query every time it generally performs requests, and since database access is one of the more expensive and time consuming things on the server side, this is quite useful.

How does JWT work

If a JWT contains user information, or information about access rights, it may seem insecure. But this is not the case, in fact, it works much in the same way as RSA certificates, and can in fact use RSA or an algorithm called HMAC. On an abstract level it works like this:

Token creation

  1. A login is attempted at the server, e.g. with username and password
  2. The server verifies the information, and creates a json object containing the relevant information
  3. The server then SIGNS the information, and serializes it.
  4. Finally the object is returned to the user.

From this point onward, there are two possibilities of what happens when a user tries to log back in:

Client access via Token

  1. The client sends the JWT to the server
  2. The server verifies the signature, resulting in one of two things:
    • Allows the client to do whatever the JWT says he or she is allowed to do
    • Verification fails, and the JWT is discarded, the client is then typically presented with HTTP 403 or similar, if the client has a gui, the user can redirected to a login page, or the credentials are cached, and the token is refreshed.

What happens when user rights, etc. are altered

One of the weaknesses of the JWT is that since it is signed by an authority, the information in it is valid until the signature (timestamp etc.) determines it is no longer so, or at least until it is checked against the database next time. This means that rights may be changed serverside by an administrator, but it may take until the whatever the refresh rate set by the server is, to deny the client the right to some action which has now been denied them.


Last update: December 12, 2023