Enabling token-based authentication with JSON Web Token

One of the most used authentication mechanisms is a token-based authentication system. With this technique, each time the user logs in, a token is generated and sent back in the response. The token is a hashed and signed value that can later be validated by the server to ensure its authenticity. After the client receives the token, it sends it back with each request (as a header), and the server will extract the user details from the token (if it's valid).
Using tokens gives you a few benefits:

  • Secure: Because the value is signed (and sometimes even ciphered), the server can be sure that the values are valid. Another added benefit in the security aspect is that, unlike with cookie-based authentication, the server is not exposed to Cross-Site Request Forgery (CSRF) attacks.
  • Stateless: Because the client is the one who holds the token, there's no need to store session-like data in the server. Being stateless makes your server more robust and scalable. 
  • Cross-origin: Because the token is just a value, it can be transferred and used from any type of client, even if it's located in a different domain.
  • Performance: Because the token can contain data that can later be extracted and reused, it reduces the round trips to the datastore, and therefore improves performance.  

The most used standard for token-based authentication is JWT (https://jwt.io/introduction/), which allows for the representation of claims securely, and sharing them between two parties.

JWT tokens are composed from three parts that are encoded in Base64 and separated by a dot (.) :
{Header}.{Payload}.{Signature}

  • Header: Holds the token type and the hashing algorithm (such as HMAC SHA256).
  • Payload: Contains claims, which are the encapsulated user data (basically, key-value pairs) and metadata such as the issuer of the token, the token expiration time, issued time, and so forth.
  • Signature: A cryptographic value that is calculated by taking the {Header}.{Payload} part and creating a hash with the hashing algorithm specified in the header, and with a secret to which we will refer to as the signing-key

Since the JWTs are encoded, they are not human-readable, so a nice web tool to know of is the JWT Debugger, which you can find at https://jwt.io/. After you get hold of a JWT, you can paste it into the tool and see the contained information.

For example, here is a JWT I created in the GiveNTake application, when the user [email protected] signed in:

The text in this image is not important. The purpose of this image is to give an idea of what the decoded JWT looks like.

To use JWTs in your application, you need to add the Microsoft.AspNetCore.Authentication.JwtBearer NuGet package and then enable it in the ConfigureServices method of your Startup class:

services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(jwtOptions =>
{
jwtOptions.TokenValidationParameters = new TokenValidationParameters()
{
ValidateActor = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = Configuration["JWTConfiguration:Issuer"],
ValidAudience = Configuration["JWTConfiguration:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWTConfiguration:SigningKey"]))
};
});

Note that I've used values that come from the application configuration. Open the appsettings.json file of your application and add a JWTConfiguration section, as shown here:

{
"ConnectionStrings": {
...
},
"JWTConfiguration": {
"Issuer": "Issuer",
"Audience": "audience",
"SigningKey": "my long enough key for authentication",
"TokenExpirationDays": 7
}
}
In the JWT example here, I configured the signing key by using SymmetricSecurityKey and retrieving the key from the configuration. In a production environment, it's not secure to store your keys in the configuration—instead, you should use a certificate (Microsoft.IdentityModel.Tokens.X509SecurityKey) or a security store such as Azure Key Vault (see Chapter 16, Taking Advantage of Cloud Services).

Now that the authentication capabilities are enabled, we can start using these capabilities in the application. First, I'll explain the end-to-end authentication and authorization flow that the user will have with the system.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.151.164