<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://www.hattangadi.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.hattangadi.com/" rel="alternate" type="text/html" /><updated>2023-09-03T08:36:49+00:00</updated><id>https://www.hattangadi.com/feed.xml</id><title type="html">Aarav Hattangadi</title><subtitle>A space for me to share my encounters with technology.</subtitle><author><name>Aarav Hattangadi</name><email>aarav@hattangadi.com</email></author><entry><title type="html">The Enigma Machine’s Ingenious Encryption</title><link href="https://www.hattangadi.com/blog/the-enigma-machines-ingenious-encryption/" rel="alternate" type="text/html" title="The Enigma Machine’s Ingenious Encryption" /><published>2023-08-19T00:00:00+00:00</published><updated>2023-08-19T00:00:00+00:00</updated><id>https://www.hattangadi.com/blog/the-enigma-machines-ingenious-encryption</id><content type="html" xml:base="https://www.hattangadi.com/blog/the-enigma-machines-ingenious-encryption/">&lt;p&gt;During the Second World War, once the Germans started using wireless communication systems, the need for encryption emerged. The encryption technique of choice for Nazi Germany was the Enigma Machine — one believed to be uncrackable. Quite ironically, the Enigma machine, one of the hardest ciphers to crack was based upon the weakest cipher, the Caesar cipher.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding the machine&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While there were many versions of the Enigma machine, I’ll be focusing on the first few — all the others just expanded upon their concepts while the core remained the same.
The machine was made up of 5 main components: a keyboard, plugboard, 3 interchangeable rotors, a reflector, and a lamp board.&lt;/p&gt;

&lt;p&gt;When a key was pressed on the keyboard, an electric signal passed through the plugboard, through the 3 rotors, through the reflector, back through the 3 rotors, plugboard, and finally the enciphered letter would illuminate on the lapboard.&lt;/p&gt;

&lt;p&gt;The plugboard allowed up to 10 pairs of letters to be swapped with one another. Swapping an A –&amp;gt; K for example, would lead to all ‘K’s being made into ‘A’s (before and after encryption) for example.&lt;/p&gt;

&lt;p&gt;Each machine had 3/more rotors, each having a distinct wiring configuration - which could be interchanged in the 3 rotor slots. Each rotor spun at different intervals. The third rotor spinning on each keypress, the second after 26 rotations of the third rotor, and the first spinning every 26 rotations of the second rotor ( = 26*26 = 676 rotations).
Each rotor had a turnover notch on which the next rotor would be turned. This meant that a letter would always be encrypted into a different letter, never repeated, and never itself. Older models included only 1 turnover notch, but with the introduction of newer models, rotors VI, VII, and VIII had two turnover notches.&lt;/p&gt;

&lt;p&gt;The rotors also had offsets, which would change their starting positions. If the starting position of a rotor was a B, the letter A would get encoded as a B, and then passed on as a B to the next rotor.&lt;/p&gt;

&lt;p&gt;While the wiring of the rotors couldn’t be changed, you could change the order of the rotors and their starting positions. Those settings were changed each day during the war, generating an enormous number of possible encryption paths for a letter.&lt;/p&gt;

&lt;p&gt;Here’s an example of how the signal would pass through the rotors:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/enigma_rotors.png&quot;&gt;&lt;img src=&quot;/assets/images/enigma_rotors.png&quot; alt=&quot;An image explaining how the rotors of enigma functioned&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the signals passed through all the three rotors, it would be passed into a reflector. A reflector is quite similar to the rotor, however, it wouldn’t rotate or change position—it had a fixed position which couldn’t be changed. However, there were 3 reflectors - A, B, and C. Once the reflector encoded the letter, the signal would be again passed through the rotors, this time in the backwards direction.&lt;/p&gt;

&lt;p&gt;This new signal was passed through the plugboard and the letter would be swapped once again, and then finally, the letter would be illuminated on the plugboard.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/assets/images/enigma_functioning.png&quot;&gt;&lt;img src=&quot;/assets/images/enigma_functioning.png&quot; alt=&quot;An image showing how the signals passed through an enigma machine&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While the core principles of Enigma weren’t so complicated, the sheer number of possibilities, settings, and randomness led to it being considered an unbreakable device for a long time.&lt;/p&gt;</content><author><name>Aarav Hattangadi</name><email>aarav@hattangadi.com</email></author><category term="uncategorized" /><summary type="html">Almost, uncrackable ...</summary></entry><entry><title type="html">My Ad-blocking adventure with NextDNS</title><link href="https://www.hattangadi.com/blog/my-ad-blocking-adventure-with-nextdns/" rel="alternate" type="text/html" title="My Ad-blocking adventure with NextDNS" /><published>2023-06-25T00:00:00+00:00</published><updated>2023-06-25T00:00:00+00:00</updated><id>https://www.hattangadi.com/blog/my-ad-blocking-adventure-with-nextdns</id><content type="html" xml:base="https://www.hattangadi.com/blog/my-ad-blocking-adventure-with-nextdns/">&lt;p&gt;A few months ago, I was on the lookout for a customizable DNS server, which would let me block ads, monitor traffic, and redirect custom domains to local IP addresses; akin to that of a &lt;a href=&quot;https://pi-hole.net/&quot;&gt;PiHole&lt;/a&gt;, but without needing to run a DNS server 24x7.&lt;/p&gt;

&lt;p&gt;On my search, I stumbled upon &lt;a href=&quot;https://nextdns.io/&quot;&gt;NextDNS&lt;/a&gt;, which is a DNS service that lets you do all of the above, and more. It has a very generous free tier (300k requests p/m&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;), offering both DNS and DoH (DNS-over-HTTPS). I’ve been using it for a few months now, and I’m very happy with it.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The setup process was a breeze—I just had to create an account, and create a profile with my required settings. Afterwhich, I just had to configure my devices to use the NextDNS servers, and I was good to go.&lt;/p&gt;

&lt;p&gt;Ad-blocking works fine as well, and I haven’t noticed any issues with it. You can mix-and-match various blocklists, I’ve found AdGuard’s ones to be the best. They can also block trackers, and affiliate links if you wish. Custom blocklists/allowlists are also supported, but I haven’t tried them out yet. I’ve also set up a few custom rules to redirect some domains to local IP addresses, and that works fine as well.&lt;/p&gt;

&lt;p&gt;The logging features are good, and you can choose where you’d like to have the logs stored (US/UK/EU/Switzerland) and for how long (1 hour -&amp;gt; 2 days). You can choose what to log as well, which seems like a plus point to me.&lt;/p&gt;

&lt;p&gt;The speed is decent as well, and I haven’t noticed any issues with it. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bulldozher&lt;/code&gt; test shows that’s its faster than Cloudflare’s, and marginally slower (+- 1ms) than Google’s.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;█ Cloudflare DNS
  1.1.1.1
   22.1 ms  32.6 ms 809.4 ms
  ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▆▆▆▆▆▆█████████████████

█ Quad9 DNS
  9.9.9.9
  272.4 ms 288.8 ms 293.5 ms
  ██████████████████████████████████████████████████

█ Google DNS
  8.8.8.8
    4.6 ms 380.0 ms 389.5 ms
       ▁▁▁▁▁▁▁▁▁▁▁▃▃▃▃▃▃████████████████████████████

█ Verisign DNS
  64.6.64.6
   60.6 ms  64.0 ms 197.0 ms
  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇███████████████████████

█ 45.90.28.60 DNS
  45.90.28.60
    5.0 ms   5.7 ms 308.5 ms
  ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▂▂▂▂▂▂▂▂▂▂▃▃▃▃▃▃██████

█ Mozilla DoH
  https://mozilla.cloudflare-dns.com/dns-query
   23.3 ms  24.8 ms 482.6 ms
  ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▅▅▅▅▅▅██████
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;They also claim to offer malware and phishing protection, but I haven’t gotten around to testing that out yet.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://nextdns.io/pricing&quot;&gt;NextDNS Pricing&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;At the time of writing, once the 300k requests are exhausted, the service will only work as a normal DNS resolver (i.e., no ad-blocking/rewrites/logging/analytics) until the next month. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>Aarav Hattangadi</name><email>aarav@hattangadi.com</email></author><category term="networking" /><category term="dns" /><summary type="html">A customizable DNS service</summary></entry><entry><title type="html">Implementing JWT authentication in ASP.NET Core</title><link href="https://www.hattangadi.com/blog/implementing-jwt-authentication-in-asp-net-core/" rel="alternate" type="text/html" title="Implementing JWT authentication in ASP.NET Core" /><published>2023-06-04T00:00:00+00:00</published><updated>2023-06-04T00:00:00+00:00</updated><id>https://www.hattangadi.com/blog/implementing-jwt-authentication-in-asp-net-core</id><content type="html" xml:base="https://www.hattangadi.com/blog/implementing-jwt-authentication-in-asp-net-core/">&lt;p&gt;In my previous article, I explored the fundamentals of JWT authentication. We delved into the structure of a token, and its benefits.
In this post, we will dive deeper into the practical implementation of JWT tokens. We’ll be using ASP.NET Core 7 along with a controller-based API.&lt;/p&gt;

&lt;p&gt;Throughout this article, I’ll guide you through the necessary steps to integrate JWT authentication into your ASP.NET Core API. We’ll explore how to generate and validate tokens, store user claims, and implement middle ware for token-based authentication. Additionally, we will highlight some best practices and considerations to ensure the security and integrity of your authentication system.&lt;/p&gt;

&lt;p class=&quot;box-note&quot;&gt;Note: For the purpose of this post, I’ll be using the project template ASP.NET Core Web API and .NET 7&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;nuget-package---jwtbearer&quot;&gt;NuGet Package - JwtBearer&lt;/h2&gt;

&lt;p&gt;First and foremost, we’ll need to install the JwtBearer package from NuGet to be able to work with JWT tokens.
The package &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Microsoft.AspNetCore.Authentication.JwtBearer&lt;/code&gt; fulfills our requirements. You can install this either by using the GUI NuGet package manager in Visual Studio (right click your project in the solution explorer, and click on manage NuGet packages) or by using the NuGet Package Manager Console and entering the following command:&lt;/p&gt;

&lt;div class=&quot;language-ps highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;Install-Package&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Microsoft.AspNetCore.Authentication.JwtBearer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;setting-secrets&quot;&gt;Setting secrets&lt;/h2&gt;

&lt;p&gt;Though secrets shouldn’t be set in an easy-to-access location, for the purpose simplicity, we’ll be using appsettings.json as an example.&lt;/p&gt;

&lt;p&gt;We’ll create a section in our appsettings.json file which will store our secrets: namely, the issuer, audience, and a secret key. These values will be used later on to generate our JWT token.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Jwt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Issuer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://example.com/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Audience&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://example.com/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A secret key - please don't use this in the production environment&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;specifying-authentication-settings&quot;&gt;Specifying authentication settings&lt;/h2&gt;

&lt;p&gt;In our program.cs file, we’ll use the AddAuthentication method to configure our JWT authentication at runtime. We’ll specify the authentication scheme as JwtBearer.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultAuthenticateScheme&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JwtBearerDefaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AuthenticationScheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultChallengeScheme&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JwtBearerDefaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AuthenticationScheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DefaultScheme&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JwtBearerDefaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AuthenticationScheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, we’ll use the AddJwtBearer method to configure the token parameters.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddJwtBearer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TokenValidationParameters&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TokenValidationParameters&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ValidIssuer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Jwt:Issuer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ValidAudience&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Jwt:Audience&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;IssuerSigningKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SymmetricSecurityKey&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UTF8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Jwt:Key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ValidateIssuer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ValidateAudience&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ValidateLifetime&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ValidateIssuerSigningKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We set the ValidIssuer, ValidAudience, and IssuerSigningKey properties with the values specified in our appsettings.json. Furthermore, we let our API know that it should only validate the Issuer, Audience, and Signing Key; it shouldn’t validate the time-based validity of the key.&lt;/p&gt;

&lt;p&gt;Now, we need to tell the builder to add the authorization service at runtime:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddAuthorization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;as well as the authentication and authorization middle ware:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseAuthorization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;user-model&quot;&gt;User Model&lt;/h2&gt;

&lt;p&gt;Now that we’ve set up our project, we need a model for our user credentials. We’ll have a User class with 2 properties: a username, and password. Feel free to modify this class with more properties.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UserName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Password&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;generating-the-tokens&quot;&gt;Generating the tokens&lt;/h2&gt;

&lt;p&gt;To let users generate the tokens, we’ll need an endpoint. This endpoint will take in the credentials from the user and return a token if the credentials are valid.&lt;/p&gt;

&lt;p&gt;Create a new controller. I’ve named it JwtController. We’ll add a HTTP Post endpoint to this.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpPost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IResult&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FromBody&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jwtUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We take in a object from the body of the request, and map it to the model of User - which we’re calling jwtUser.&lt;/p&gt;

&lt;p&gt;Our endpoint checks if the username and password match (though, it’s best practice to store credentials in a database; or you could use ASP.NET Core’s Identity Manager). The issuer, audience, and key are set to those we specified in the appsettings.json file. A new TokenDescriptor is created which will add our claims to the token. The claim &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Id&lt;/code&gt; is a GUID, the subject and email are set to the provided username, and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Jti&lt;/code&gt; claim is also set to a GUID. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Jti&lt;/code&gt; claim is an id for the JWT which can be used to enhance the security of our token. The expiration of the token is then set to 5 minutes, and the signing algorithm is set to HmacSha512. We then use the JwtSecurityTokenHandler to create the token, and return it along with a HTTP Code of 200.&lt;/p&gt;

&lt;p&gt;If the username and password isn’t valid, a HTTP Code of 401 for unauthorized is sent.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;admin&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Password&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;issuer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Jwt:Issuer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;audience&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Jwt:Audience&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ASCII&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetBytes&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Jwt:Key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenDescriptor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SecurityTokenDescriptor&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Subject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ClaimsIdentity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Claim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Guid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;NewGuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Claim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JwtRegisteredClaimNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Claim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JwtRegisteredClaimNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Claim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JwtRegisteredClaimNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Jti&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Guid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;NewGuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
             &lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Expires&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UtcNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddMinutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Issuer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;issuer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Audience&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;audience&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SigningCredentials&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SigningCredentials&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SymmetricSecurityKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SecurityAlgorithms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HmacSha512Signature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenHandler&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;JwtSecurityTokenHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jwtToken&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jwtToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Unauthorized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;making-endpoints-require-authentication&quot;&gt;Making endpoints require authentication&lt;/h2&gt;

&lt;p&gt;To make controllers require a token for authorization, we need to add a decorator of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[Authorize(AuthenticationSchemes = &quot;Bearer&quot;)]&lt;/code&gt; to the desired controller. If the token is considered valid, the request will pass through, else a 401 response would be returned.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;In this article, we covered the key steps involved in implementing JWT authentication in an ASP.NET Core API. We installed the required NuGet package, configured secrets and authentication settings. To allow users to generate tokens, we create an endpoint and added essential claims to the token. We applied the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[Authorize]&lt;/code&gt; attribute to a controller to make it accessible only to users with valid tokens.
We’ve just implemented a part of token-based authentication — security is an ongoing concern, and you should think about implementing additional measures like refresh tokens, and token revocation.&lt;/p&gt;

&lt;p&gt;Stay up to date with security best practices to ensure the long-term resilience of your application. Happy coding!&lt;/p&gt;</content><author><name>Aarav Hattangadi</name><email>aarav@hattangadi.com</email></author><category term="authentication" /><category term="asp.net" /><summary type="html">In my previous article, I explored the fundamentals of JWT authentication. We delved into the structure of a token, and its benefits. In this post, we will dive deeper into the practical implementation of JWT tokens. We’ll be using ASP.NET Core 7 along with a controller-based API.</summary></entry><entry><title type="html">Understanding JWT-Based Authentication</title><link href="https://www.hattangadi.com/blog/understanding-jwt-based-authentication/" rel="alternate" type="text/html" title="Understanding JWT-Based Authentication" /><published>2023-05-30T00:00:00+00:00</published><updated>2023-05-30T00:00:00+00:00</updated><id>https://www.hattangadi.com/blog/understanding-jwt-based-authentication</id><content type="html" xml:base="https://www.hattangadi.com/blog/understanding-jwt-based-authentication/">&lt;p&gt;Today, we’ll delve into the intricacies of JWT based authentication, a powerful method to secure your applications.&lt;/p&gt;

&lt;h2 id=&quot;the-jwt-passport&quot;&gt;The JWT “Passport”&lt;/h2&gt;

&lt;p&gt;Think of JWT Tokens like digital passports, similar to those you use while travelling. It consists of 3 essential components: the header, the payload, and the signature.&lt;/p&gt;

&lt;p&gt;The header is like the cover of our passport, providing necessary information. It contains metadata about the token, such as the hashing algorithm used and the type of token it represents.&lt;/p&gt;

&lt;p&gt;Next, we have the payload, which is the core of our JWT passport. This section carries the actual data, much like the personal information page of your passport. This includes details about the user, such as their name, email, role, or any other relevant information, which are known as &lt;em&gt;claims&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Last but not least, we have the signature, the security seal of our JWT passport. This signature is generated using a secret key known only to the server. It ensures the integrity of the token, just like the anti-counterfeiting measures in your passport that prevent any tampering or forgery.&lt;/p&gt;

&lt;h2 id=&quot;authenticating-with-your-token&quot;&gt;Authenticating with your token&lt;/h2&gt;

&lt;p&gt;Now, let’s see how JWT tokens work in practice. When a user logs in to a web application, the server generates a JWT token and sends it to the application.&lt;/p&gt;

&lt;p&gt;Once you have your JWT token, you present it with every subsequent request to prove your identity. The server can then verify the authenticity and integrity of the token by validating the signature using the secret key and verifying that the necessary claim requirements are met (think: user role). If everything checks out, you’re granted access to the requested resources.&lt;/p&gt;

&lt;h2 id=&quot;stateless-tokens&quot;&gt;Stateless tokens&lt;/h2&gt;

&lt;p&gt;One of the benefits of JWT authentication is statelessness. Unlike traditional session-based authentication, where the server needs to keep track of session data, JWT tokens are self-contained. They carry all the necessary information within themselves, making the authentication process lightweight and scalable.&lt;/p&gt;

&lt;p&gt;The server can focus on processing requests efficiently. This also allows for easy horizontal scaling, as any server in a cluster can handle a request without relying on shared session data.&lt;/p&gt;

&lt;h2 id=&quot;practical-example&quot;&gt;Practical Example&lt;/h2&gt;

&lt;p&gt;To experience JWT authentication in action, you can check out the JWT generator at &lt;a href=&quot;https://jwt.io&quot;&gt;jwt.io&lt;/a&gt;. This tool allows you to create JWT tokens by specifying the header, payload, and secret key. It also provides a simple way to decode and verify tokens, giving you a hands-on understanding of how JWT works.&lt;/p&gt;

&lt;p&gt;A token looks like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huQGRyaWZ0bmV0d29ya3MubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.eSxXOKmuJVnan8fM2fvj65Dq5SjtI-kx_qXDzdshDc4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this token, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt; is used as a separator between the different parts. Let’s break down the token into its components and explore their significance:&lt;/p&gt;

&lt;p&gt;Header:
The first part of the token is the header. When decoded, it results in the following JSON output:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;alg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;HS256&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;typ&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;JWT&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The header provides essential metadata about the token. In this example, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alg&lt;/code&gt; (algorithm) indicates that the HS256 algorithm was used to hash the token, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;typ&lt;/code&gt; (type) indicates that this is a JWT token.&lt;/p&gt;

&lt;p&gt;Payload:
The second part of the token is the payload. When decoded, it results in the following JSON output:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;sub&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567890&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;John Doe&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;john@driftnetworks.net&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1516239022&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The payload contains the actual data about the user who is requesting the resource. In this example, the payload includes the following information:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sub&lt;/code&gt; (subject): It refers to the subject whom the token represents, identified by the value 1234567890.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;: It specifies the name of the requesting user as “John Doe”.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;email&lt;/code&gt;: It provides the email address of the user as “john@driftnetworks.net”.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iat&lt;/code&gt; (issued at): It indicates the time at which the token was issued, represented as the number of seconds since the UNIX epoch (January 1, 1970, 00:00:00 UTC). In this case, the value is 1516239022.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The payload can contain additional claims based on the specific requirements of your application, such as user roles, permissions, or any custom data you need to associate with the token.&lt;/p&gt;

&lt;p&gt;While this is an example of a generic JWT token, they may also include other parameters, like expiry times (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exp&lt;/code&gt;), audience (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aud&lt;/code&gt;), issuer (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iss&lt;/code&gt;), and many others, which provide further control.&lt;/p&gt;</content><author><name>Aarav Hattangadi</name><email>aarav@hattangadi.com</email></author><category term="authentication" /><summary type="html">Today, we’ll delve into the intricacies of JWT based authentication, a powerful method to secure your applications.</summary></entry></feed>