<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aarav Hattangadi</title>
    <description>The latest articles on DEV Community by Aarav Hattangadi (@ahattangadi).</description>
    <link>https://dev.to/ahattangadi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1091859%2F194cd855-9519-405b-b2de-9431d1958485.png</url>
      <title>DEV Community: Aarav Hattangadi</title>
      <link>https://dev.to/ahattangadi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahattangadi"/>
    <language>en</language>
    <item>
      <title>My Ad-Blocking and Rewriting adventure with NextDNS</title>
      <dc:creator>Aarav Hattangadi</dc:creator>
      <pubDate>Sat, 24 Jun 2023 19:29:13 +0000</pubDate>
      <link>https://dev.to/ahattangadi/my-ad-blocking-and-rewriting-adventure-with-nextdns-3488</link>
      <guid>https://dev.to/ahattangadi/my-ad-blocking-and-rewriting-adventure-with-nextdns-3488</guid>
      <description>&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="https://pi-hole.net/"&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="https://nextdns.io/"&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="fnref1"&gt;1&lt;/sup&gt; &lt;sup id="fnref2"&gt;2&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;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&gt;bulldozher&lt;/code&gt; test shows that's its faster than Cloudflare's, and marginally slower (+- 1ms) than Google's.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&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;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;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://nextdns.io/pricing"&gt;NextDNS Pricing&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&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;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>dns</category>
      <category>networking</category>
    </item>
    <item>
      <title>Implementing JWT authentication in ASP.NET Core</title>
      <dc:creator>Aarav Hattangadi</dc:creator>
      <pubDate>Sat, 03 Jun 2023 15:38:17 +0000</pubDate>
      <link>https://dev.to/ahattangadi/implementing-jwt-authentication-in-aspnet-core-43f9</link>
      <guid>https://dev.to/ahattangadi/implementing-jwt-authentication-in-aspnet-core-43f9</guid>
      <description>&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.&lt;br&gt;
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;blockquote&gt;
&lt;p&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;/blockquote&gt;


&lt;h2&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.&lt;br&gt;
The package &lt;code&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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight postscript"&gt;&lt;code&gt;&lt;span class="nf"&gt;Install-Package&lt;/span&gt; &lt;span class="nf"&gt;Microsoft.AspNetCore.Authentication.JwtBearer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&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;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultAuthenticateScheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JwtBearerDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationScheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultChallengeScheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JwtBearerDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationScheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultScheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JwtBearerDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationScheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...    &lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;AddJwtBearer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TokenValidationParameters&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TokenValidationParameters&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ValidIssuer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Jwt:Issuer"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;ValidAudience&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Jwt:Audience"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;IssuerSigningKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SymmetricSecurityKey&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Jwt:Key"&lt;/span&gt;&lt;span class="p"&gt;])),&lt;/span&gt;
        &lt;span class="n"&gt;ValidateIssuer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ValidateAudience&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ValidateLifetime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ValidateIssuerSigningKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;   
    &lt;span class="p"&gt;};&lt;/span&gt;    
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthentication&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthorization&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;UserName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&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;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IResult&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;jwtUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&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&gt;Id&lt;/code&gt; is a GUID, the subject and email are set to the provided username, and a &lt;code&gt;Jti&lt;/code&gt; claim is also set to a GUID. The &lt;code&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;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&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&gt;[Authorize(AuthenticationSchemes = "Bearer")]&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;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&gt;[Authorize]&lt;/code&gt; attribute to a controller to make it accessible only to users with valid tokens.&lt;br&gt;
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;

</description>
      <category>beginners</category>
      <category>security</category>
      <category>aspdotnet</category>
    </item>
    <item>
      <title>Understanding JWT-Based Authentication</title>
      <dc:creator>Aarav Hattangadi</dc:creator>
      <pubDate>Mon, 29 May 2023 19:03:25 +0000</pubDate>
      <link>https://dev.to/ahattangadi/understanding-jwt-based-authentication-5821</link>
      <guid>https://dev.to/ahattangadi/understanding-jwt-based-authentication-5821</guid>
      <description>&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&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&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&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&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="https://jwt.io"&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;br&gt;
&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huQGRyaWZ0bmV0d29ya3MubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.eSxXOKmuJVnan8fM2fvj65Dq5SjtI-kx_qXDzdshDc4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this token, the &lt;code&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:&lt;br&gt;
The first part of the token is the header. When decoded, it results in the following JSON output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john@driftnetworks.net"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1516239022&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&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&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&gt;name&lt;/code&gt;: It specifies the name of the requesting user as "John Doe".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;email&lt;/code&gt;: It provides the email address of the user as "&lt;a href="mailto:john@driftnetworks.net"&gt;john@driftnetworks.net&lt;/a&gt;".&lt;/li&gt;
&lt;li&gt;
&lt;code&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&gt;exp&lt;/code&gt;), audience (&lt;code&gt;aud&lt;/code&gt;), issuer (&lt;code&gt;iss&lt;/code&gt;), and many others, which provide further control.&lt;/p&gt;

</description>
      <category>security</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
