Securing a web application is one of the most important to do and usually one of the hardest things to pull off. In this series, we are going to learn how to implement authentication with Angular on the front end side and ASP.Net Core on the server side using the JSON web tokens (JWT).

We are also going to learn how authentication works in general and how to utilize JSON web tokens to securely transmit user’s credentials from the server to the client and vice versa.

Therefore, we are going to divide this series into two parts. In the first part, we are going to implement backend service with ASP.NET Core and authentication with JWT (JSON web token) integration. In the second part, we are going to implement front-end features like login, logout, securing routes and more with Angular.

The source code for this part can be found on this GitHub repo.

This post is divided into several sections:

The Big Picture

Before we get into the implementation of authentication and authorization, let’s have a quick look at the big picture. There is an application that has a login form. A user enters its username, password and presses the login button. After pressing the login button, a client (eg web browser) sends the user’s data to the server’s API endpoint.web authentication big picture When the server validates the user’s credentials and confirms that the user is valid, it’s going to send an encoded JWT to the client. JSON web token is basically a JavaScript object that can contain some attributes of the logged-in user. It can contain a username, user subject, user roles or some other useful information.

At the client side, we store the JWT in browser’s local storage to remember user’s login session. We may also use the information from the JWT to enhance the security of our application as well.

Introduction to JSON Web Tokens

JSON web tokens enable a secure way to transmit data between two parties in a form of a JSON object. It’s an open standard and it’s a popular mechanism for web authentication. In our case, we are going to use JSON web tokens to securely transfer a user’s data between the client and the server.

JSON web tokens consist of three basic parts: the header, payload, and the signature.

One real example of JSON web token:

JWT example

Every part of all the three parts is shown in a different color:

Header

The first part of JWT is the Header, which is a JSON object encoded in the base64 format. The header is a standard part of JWT and we don’t have to worry about it. It contains the information like the type of token and the name of the algorithm.

Header Sample:

Payload

After the Header, we have a Payload which is also a JavaScript object encoded in the base64 format. The payload contains some attributes about the logged-in user. For example, it can contain user id, user subject, and the information about whether a user is an admin user or not. JSON web tokens are not encrypted and can be decoded with any base64 decoder so please never include sensitive information in the Payload.

Payload sample:

Signature

Finally, we have the Signature part. Usually, the server uses the signature part to verify whether the token contains a valid information, the information which server is issuing. It is a digital signature that gets generated by combining the header and the payload together. Moreover, its based on a secret key that only server knows.

JWT signature composition

So, if malicious users try to modify the values in the payload, they have to recreate the signature and for that purpose, they need the secret key which the only server has. At the server side, we can easily verify if the values are original or not by comparing the original signature with a new signature computed from the values coming from the client.

So, we can easily verify the integrity of our data just by comparing the digital signatures. This is the reason why we use JWT.

Creating ASP.NET Core Web Service

Now let’s create a brand new ASP.NET Core project. We can create a new Web API project with .NET Core CLI or you can use Visual Studio 2017. We are going to use the CLI for this demo so if you don’t want to install Visual Studio 2017, you don’t have to. Once we create the project you can open it with any code editor like Visual Studio Code, Notepad++, WebStorm or even Visual Studio.

To create a new Web API project with .NET Core CLI we need to:

  • Open a command line terminal (cmd)
  • Navigate the terminal window to the directory where we want to create the project
  • Run the command:

As a result, we are going to have a new .NET Core Web API project template in the current directory with some boilerplate code. Additionally, let’s navigate the terminal window to the project’s root directory.

We need to navigate to our project:

And run the application locally:

As a result, this is going to spin up a web server locally and it will host our application at http://localhost:5000. If you type the same address in browser’s address bar, you are going to get no response as there is no resource available at that endpoint. Now let’s type http://localhost:5000/api/values to get some result:

HTTP GET request response

Awesome! So far so good.

In the next step, we are going to configure JWT authentication in our application.

Configuring JWT Authentication

To configure JWT authentication in .NET Core, we need to modify Startup.csfile. It’s a bootstrapper class that runs when our application starts. Inside the file, we have the ConfigureSerivces method that adds services to the IServiceCollection container, thus making them available for the constructor injection.

JWT’s support is built into ASP.NET Core 2.0 and we are going to configure an authentication middleware for JSON web tokens.

For the sake of simplicity, we are going to add all the code inside the ConfigureServices method. But the better practice is to use Extension methods so we could free our ConfigureServices method from extra code lines. If you want to learn how to do that, and to learn more about configuring the .NET Core Web API project, check out: .NET Core Service Configuration.

We need to modify the ConfigureServices method to add the JWT support:

Code Explanation

Firstly, we register the JWT authentication middleware by calling the method AddAuthentication on the ISerivceCollectioninterface. Next, we specify the authentication scheme JwtBearerDefaults.AuthenticationScheme. We also provide some parameters that will be used while validating JWT.

Excellent.

We’ve successfully configured the JWT authentication.

According to the configuration, the token is going to be valid if:

  • The issuer is the actual server that created the token (ValidateIssuer=true)
  • The receiver of the token is a valid recipient (ValidateAudience=true)
  • The token has not expired (ValidateLifetime=true)
  • The signing key is valid and is trusted by the server (ValidateIssuerSigningKey=true)

Additionally, we are providing values for the issuer, audience and the secret key that the server uses to generate the signature for JWT. We are going to hardcode both username and password for the sake of simplicity. But, the best practice is to put the credentials in a database or a configuration file or to store the secret key into the environment variable.

We need to do one more step to make our authentication middleware available to the application.

Add the app.UseAuthentication() in the Configure method:

And that’s all we need to configure the JWT authentication in ASP.NET Core.

Securing API Endpoints

We already have an API endpoint api/values to get an array of values and that endpoint is not secure. Anyone can send a request to http://localhost:5000/api/values to fetch the values. So, in this section, we are going to add a new api/customers endpoint to serve a list of the customers.  This endpoint is going to be secure from anonymous users and only logged-in users can consume it.

Now let’s add an MVC CustomersController in the Controllers folders. Inside the controller, we are going to add a Get action method that is going to return an array of the customers. More importantly, we are going to add an extra security layer by decorating action method with the[Authorize] attribute so only logged-in users can access the route.

Let’s modify the CustomersController class:

Authorize attribute on top of the GET method restricts the access to only authorized users. Only users who are logged-in can access the list of customers. Therefore, this time if you make a request to http://localhost:5000/api/customers from the browser’s address bar, instead of getting a list of customers you are going to get a 401 Not Authorized response.

HTTP 401 Not Authorized response

Adding Login Endpoint

To authenticate anonymous users, we have to provide a login endpoint so the users can log-in and access protected resources. A user is going to provide a username, password and if the credentials are valid we are going to issue a JSON web token for the requesting client.

In addition, before we start implementing the authentication controller we need to add a LoginModel to hold user’s credentials on the server. LoginModel is a simple class that contains two properties: UserName and Password.  We are going to create a Models folder in the root directory and inside it a LoginModel class:

Now let’s create the AuthController inside the Controllers folder. Inside the AuthControllerwe are going to validate the user’s credentials. If the credentials are valid, we are going to issue a JSON web token. For this demo, we are going to hardcode the username and password to implement a fake user. After validating the user’s credentials we are going to generate a JWT with a secret key. JWT uses the secret key to generate the signature.

Let’s implement the AuthController:

Code Explanation

First of all, notice the use of the [HttpPost] attribute. After applying this attribute to action methods as a result the API endpoint only responds to HTTP POST requests. Inside the login method, we are creating the SymmetricSecretKey with the secret key value [email protected] Then, we are creating the objec SigningCredentials and as arguments, we provide a secret key and a name of the algorithm that we are going to use to encode the token.

Here comes the interesting part.

The first two steps are the standard steps that you don’t need to worry about. The third step is the one that we are interested in. In the third step we are creating the JwtSecurityToken object with some important parameters:

  • Issuer: The first parameter is a simple string representing the name of the web server that issues the token
  • Audience: The second parameter is a string value representing valid recipients
  • Claims: The third argument is a list of user roles, for example, the user can be an admin, manager or author (we are going to add roles in the next post)
  • Expires: The fifth argument is DateTime object that represents the date and time after which the token expires

Finally, we create a string representation of JWT by calling the WriteToken method on JwtSecurityTokenHandler. Finally, we are returning JWT in a response. As a response, we have created an anonymous object that contains only the Token property.

Testing the Login API

To test the login API:

So, let’s save all the files, navigate to the root directory of the project and run the application with the .NET Core CLI command:

Let’s launch YARC (Yet Another Rest Client) client chrome extension or any other web proxy tool that is capable of composing and sending web requests over HTTP. (You can use your preferred REST client).

In the request settings options, we are going to enter the URL: http://localhost:5000/api/auth/login, choose POST request option from the right side and paste  in the payload the JSON data:

Authentication POST request for the JWT
And press the send request button.

In the response section, we are going to see a 200 OK response with the JWT string in the response body:Login request response in YARC

Conclusion

By reading this post you have learned:

  • More about security  and how it is a crucial part of a web application development
  • What JWTs are and how they fit in the implementation of web security
  • How to create a web service with ASP.NET Core
  • How to secure API endpoints with Authorize attribute
  • And how to implement a login mechanism on the server

In the next part, we are going to implement a front end side of our application with Angular. We are going to implement login, logout, authorization, secure the routes and much more.

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published Angular content we encourage you to subscribe to our blog.