Christian Schou
  • Casa
  • Blog
    • Programação
      • C#
      • PowerShell
      • Python
      • SQL
    • WordPress
      • Tutoriais
    • Nuvem
    • Automação residencial
      • Assistente Doméstico
        • Node-Red
    • Career
  • Serviços
  • Glossário
  • About
No Result
View All Result
Christian Schou
  • Casa
  • Blog
    • Programação
      • C#
      • PowerShell
      • Python
      • SQL
    • WordPress
      • Tutoriais
    • Nuvem
    • Automação residencial
      • Assistente Doméstico
        • Node-Red
    • Career
  • Serviços
  • Glossário
  • About
No Result
View All Result
Christian Schou
No Result
View All Result
Home Programação
json web token

O que é um JSON Web Token (JWT) e por que usá-lo em conjunto com APIs da Web?

by cristã
sexta-feira, julho 1, 2022
in Programação
0

Então, o que exatamente é um token da Web JSON (JWT)? Quase todas as APIs da Web estão protegidas de alguma forma. Conheço apenas algumas APIs da Web que não são seguras e são oferecidas pela União Europeia para que os aplicativos validem dados sobre empresas, etc... Mas não é disso que trata o artigo.

Neste artigo, direi o que é um JSON Web Token (JWT) e por que você os usaria para proteger sua API da web. Se você estiver pronto, vamos começar.

Tabela de conteúdos
  1. O que é um token da Web JSON?
  2. Estrutura de um token da Web JSON
    • The JWT header
    • The JWT Payload/Body
    • The JWT Signature
  3. How does a JSON Web Token work?
  4. Validation of JWTs
    • Validate against the issuer or not?
    • Key claims to validate every time
  5. JSON Web Token Pros and Cons
  6. Why use a JSON Web Token in your Web API?
    • Can contain custom data
    • Validation can be done offline
    • Expiration is built-in
  7. Summary

O que é um token da Web JSON?

JWT is short for JSON Web Token – I will use both versions throughout this article. A JSON Web Token is a defined format developers use to exchange claims between two applications. A typical token would consist of claims in the JSON format (hence the J for JSON) accompanied by a mechanism for encrypting and signing the JSON in order for other applications to trust it.

When I started working with JWTs I had a look at the standard for JSON Web Tokens (I always do that, if there are any standards available for the tech I’m working with or starting to learn). Fortunately, there is for JWT – you can take a look for yourself here: RFC 7519. That article explicitly defines common claims for a JSON Web Token (check section 4) – below is a brief summary for each of them.

  • “iss” – (Issuer) Claim. The issuer is the way to identify the principal that issues the JWT.
  • “sub” – (Subject) Claim. This claim identifies the principal that is the subject of the JWT. In other words, this could be a user id to instruct other applications on who or what they are working with.
  • “aud” – (Audience) Claim. This claim is used to tell the consumer/recipient what the JWT is intended for. Normally this would be used for the principal to identify itself with a specific value in the claim.
  • “exp” – (Expiration Time) Claim. This claim is used to tell the systems when a JWT must NOT be accepted for processing. In other words, the claim required that the current time has to be before the expiration listens in the exp claim inside the token.
  • “nbf” – (Not Before) Claim. A token where the not before the claim is before the actual time of the consumer must not be accepted for processing. This means that the claims required the system to validate that the token can only be used if the time is after or equal to the not before the time listed inside the nbf claim.
  • “iat” – (Issued At) Claim. This is a simple one, but very important. This claim identifies the time at which the JSON Web Token was issued. The consuming application can use this claim to determine the age of the JWT.
  • “jti” – (JWT ID) Claim. This is a unique ID for each token issued by the token provider. If you are using multiple JWT providers, you must ensure that they do not create the same identifier as you would end up with a collision.

Now you should have a brief understanding of what the common claims in a JWT are giving you a better understanding of the next section, but before we move on, I want to tell a bit more about what a JWT is. The primary purpose of using a JWT is not to hide the data but to ensure that the data transferred between the server and client is sent only if the client is authenticated. This is very important – JSON Web Tokens are not encrypted, they are signed.

A JSON Web Token is actually a token-based stateless authentication mechanism. The great thing about JWTs is that they are client-side based (when talking sessions). This means that the server doesn’t have to rely totally on a database to save the information about the session – awesome!

Estrutura de um token da Web JSON

A JSON Web Token is made up of three parts. A header, a body, and a signature. When you see a JWT it would look like this: header.payload.signature.

JSON Web Token
jwt.io

So this would be a valid encoded JSON Web Token using HS256 as the algorithm. Each part is base64 encoded and concatenated using a dot “.”.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  
your-256-bit-secret

)

The JWT header

The header is a JSON object and would in normal circumstances consist of two properties. These properties are the token type and the signing/encoding algorithm. Algorithms used with JSON Web Tokens are:

  • HMAC (RFC 2104)
  • SHA256 (RFC 4634)
  • RSA (RFC 3447)
  • HS256 or RS256 (RFC 7518)

A typical header would look like this:

{
  "alg": "HS256",
  "typ": "JWT"
}

The JWT Payload/Body

The body or payload would consist of the data being issued by the authentication provider. A normal payload would consist of a lot of details/claims about the user like name, roles, last login, IP, etc… Below are some standard claims to give you an idea:

{
"sub": "1234567890",
"iat": 1516239022,
"role": "user",
"user_id": "user2"
"name": "John Doe"
"mail": "[email protected]"
}

I would never recommend putting sensitive data in a JWT like a password as a JWT easily could be decoded and compromise sensitive data about the client.

The JWT Signature

I will not be deep-diving into how the signature is encoded but I believe that it probably is the most important part of the JSON Web Token apart from the payload. The signature is calculated by encoding the header and payload using base64url and concatenating them as I mentioned above and handing them over to the algorithm responsible for the cryptographic.

If we should generate a JwtToken in ASP.NET Core, we could accomplish it by doing this:

private async Task<JwtToken> GenerateNewJWToken(ApplicationUser user)
{
    // Put it all together
    var userClaims = await _userManager.GetClaimsAsync(user);
    var roles = await _userManager.GetRolesAsync(user);
    var roleClaims = new List<Claim>();
    for (int i = 0; i < roles.Count; i++)
    {
        roleClaims.Add(new Claim("roles", roles[i]));
    }
    var claims = new[]
    {
        // jti claim + custom user object claims
        new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
        new Claim(JwtRegisteredClaimNames.Email, user.Email),
        new Claim("uid", user.Id),
        new Claim("first_name", user.FirstName),
        new Claim("last_name", user.LastName),
    }
    .Union(userClaims)
    .Union(roleClaims);

    // Generate JWT Token

    // Symmetric key and signing
    var symmetricKey = new SymmetricKey(Encoding.UTF8.GetBytes(<JWT_SYMETRIC_SECURITY_KEY>));
    var signingCres = new SigningCreds(symmetricKey, SecurityAlgorithms.HmacSha256);

    var jwtToken = new JwtToken(
        issuer: _jwtSettings.Issuer,
        audience: _jwtSettings.Audience,
        claims: claims,
        notBefore: DateTime.UtcNow,
        expires: DateTime.UtcNow.AddMinutes(_jwtSettings.DurationInMinutes),
        signingCreds: signingCreds);
    return jwtToken;
        }

As you might have guessed – whenever the header or payload changes, the signature has to be calculated one more time. At all times the idP (Identity Provider)/Authentication Provider has the private key to calculate this signature, making the token secure as it cannot be tampered with.

How does a JSON Web Token work?

The client is requesting the identity provider (idP) for login with credentials (username + password). The idP then generates a JWT certifying the user identity. This JWT is a key for the client to authorize itself against a protected resource. The JSON Web token is actually sent in the header of the request when requesting a GET, POST, PUT or DELETE command to the resource server. Let’s break it down:

  1. The user is signing into idP (Facebook, Azure AD, Google, Keycloak, FusionAuth, etc…)
  2. The identity provider is verifying the user credentials and upon success returns a JWT signed with a secret key.
  3. The user forwards this JWT when requesting a protected endpoint at the resource server inside the header of the request.
  4. The resource server then verifies against Facebook, Azure AD, Google, etc… that the token is valid using the public key.
  5. The resource server then returns a true/false response whether the token is valid and issued by them for that client. This would authorize them and give them a role that allows them to perform actions at the resource server.
json web token, jwt

If you need this diagram inside your own documentation, you can download it by clicking it. That would take you to draw.io.

Validation of JWTs

The awesome thing about JSON Web Tokens s that it’s an open-source library where we get the software to generate the JWTs but also software to do all the heavy validation work for us. The library will provide you with a mechanism to validate the format of the token, and time claims, and then verify the signature.

Validate against the issuer or not?

If you want to remove a possible bottleneck, you could remove the part where the token is validated against the issuer. This is a key decision! If you have signed the JSON Web Token, then you got an option to do the validation locally within the resource server and not depend on a third-party identity provider.

Why would you do this? If you want to go the distributed way for your application, this would be the ideal option as the identity provider would not become a bottleneck at runtime. The great thing about JWTs is that we can include custom claims as I showed earlier. We could make sure that the token contained enough data about the user authenticating so that we are not forced to contact the idP and get the data.

What about security? In some cases, a JWT could be compromised and the only way to prevent usage of it is by checking if it’s blacklisted at the identity provider. I have seen the lifespans of some JWT for months and if such a token is compromised and not blacklisted it could cause a lot of damage. To be sure when validating a token every time, I would go with the validation against the identity provider.

Key claims to validate every time

When doing the validation you always check the signature, it’s crucial! Besides the signature, we also have to verify the following claims:

  • “exp” (Expiration) – Current date must not be after the “exp” date.
  • “nbf” (Not before) – Current data must not be before the “nbf” date.

If you got any custom claims I would always make sure to validate that they have valid values, etc…

JSON Web Token Pros and Cons

JWT got like any other authentication mechanism some pros and cons. Below is a shortlist of some of the JSON Web Token pros and cons that came to my mind, when doing a little reflection on the topic.

Pros
  • Used Across Services
  • No database table
  • Simple to use
  • Expiration is built-in
  • Validation can be made offline
  • Can contain custom claims (data)
Cons
  • One key to secure it all
  • You cannot manage the client from the server
  • Relies on the signing algorithm, which means that it could be deprecated in terms of the cryptographic algorithm
  • Bigger than a normal session token
  • Revoking a session of a user is difficult as we do not own the idP server

Why use a JSON Web Token in your Web API?

JWTs are used for authorization and provide an application with a number of benefits compared to the alternatives we got when talking about authorization. I’m here referencing API keys, user:pass credentials, etc…

I would pick JSON Web Tokens because of the following reasons:

Can contain custom data

When working with JWTs we can include a lot of custom claims with data about the subject. When I build APIs I add role authorization on the controllers and specific endpoints in the controller, to make sure that no user is accessing anything they are not allowed to. The roles can be included in the payload under a custom claim.

Validation can be done offline

I mentioned it before under the validation of JWTs section. If the identity provider is using an asymmetric signing algorithm our resource server doesn’t have to request the idP and validate the token. We only have to make sure that the resource server got the public key. By using the public key we can decrypt the JWT and validate that nbf, exp, etc… is as we expected – all on our resource server without contacting the identity provider.

Expiration is built-in

The identity provider issuing the JSON Web Token can enforce the expiration of any JWT at any time, even when the expiration in the JWT is not exceeded. If using multiple JWTs in an application we can offer the client long-time access by overlapping the lifespan of each issued JWT giving the user a better experience.


Typical credentials like username and password would under normal circumstances not expire unless a system administrator has configured password lifetime for a specific period. These credentials have to be validated at the same provider every time as it holds the user database. Often you will see these credentials shared across many applications making the applications more vulnerable as it’s easier to compromise several platforms when you got the primary credentials.

On the other hand, if we do separate the generation and validation of our JSON Web Tokens, we can spread the logic into multiple places. This would allow for the API to decompose logic as there is no single place everything has to be carried out. If we do this we could also introduce multiple identity providers in the same application. This would allow your users to sign in with Google, Facebook, Azure AD, LinkedIn, Keycloak realms, FusionAuth, etc…

Summary

I hope that you learned a thing or two about JSON Web Tokens. An important thing to remember from this article is that you always should sign your JWTs with an asymmetric key so that they can be validated offline if you get the requirement in the future. Remember they are not bulletproof! If you got any sensitive data inside the JSON Web Token I would recommend you encrypt the information.

You can use jwt.io to test and validate your JSON Web Token. It is an online tool to generate examples of tokens – I used it to generate the token I have been using in this article. One more thing – don’t start coding this yourself. If you do a simple Google search you will find multiple open-source libraries to handle all the logic you need to implement JWTs in your application.

If you got any questions or suggestions, please let me know in the comments section below. If you learned something from this article or enjoyed the content, please give it a clap [pixfort_likes].

Tags: APIAuthenticationAuthorizationClaimDevelopmentJSONJSON Web TokenJWTRFC 7519Web
Previous Post

The ultimate list of useful Node-RED Home Automation nodes for your flows

Next Post

How to use Azure Blob Storage in an ASP.NET Core Web API to list, upload, download, and delete files

cristã

cristã

Hello 👋 My name is Christian and I am 26 years old. I'm an educated Software Developer with a primary focus on C#, .NET Core, Python, and PowerShell. Currently, I'm expanding my skills in Software Robots and Cloud Architecture. In some of my spare time, I share my knowledge about tech stuff on my blog.

Related Posts

watchdog
ASP.NET Core

The #1 guide to show real-time .NET 6 logs for Web Apps and APIs in a modern way using WatchDog for Free

by cristã
sábado, agosto 13, 2022
0

A reader recently asked me for a more modern way to view log files for requests and exceptions in a...

Read more
restful web api

How to build a RESTful Web API using ASP.NET Core and Entity Framework Core (.NET 6)

segunda-feira, julho 25, 2022
dynamically register entities

How to Dynamically Register Entities in DbContext by Extending ModelBuilder?

sábado, julho 23, 2022
Dockerize ASP.NET Core

How to Compose an ASP.NET Core Web API (.NET 6) with an MS SQL Server 2022 on Linux in Docker

terça-feira, julho 19, 2022
sql views

SQL Views – A Complete 101 guide to work with SQL Views

domingo, agosto 7, 2022
Next Post
azure blob storage

How to use Azure Blob Storage in an ASP.NET Core Web API to list, upload, download, and delete files

Deixe um comentário Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Christian Schou

Christian Schou

Software Developer

Hello - my name is Christian and I am 26 years old. I'm an educated Software Developer with a primary focus on C#, .NET Core, Python, and PowerShell. Currently, I'm expanding my skills in Software Robots and Cloud Architecture. In some of my spare time, I share my knowledge about tech stuff on my blog.

Recent articles

personal website
Career

Top 6 things to add on your personal website to get hired for a tech job

by cristã
domingo, agosto 7, 2022
0

Back in the days before the internet was a thing like it is today, we used to have business cards...

Read more
watchdog

The #1 guide to show real-time .NET 6 logs for Web Apps and APIs in a modern way using WatchDog for Free

sábado, agosto 13, 2022
get hired for a tech job

5 tips to help you get hired for a tech job

domingo, julho 31, 2022
restful web api

How to build a RESTful Web API using ASP.NET Core and Entity Framework Core (.NET 6)

segunda-feira, julho 25, 2022
dynamically register entities

How to Dynamically Register Entities in DbContext by Extending ModelBuilder?

sábado, julho 23, 2022

Christian Schou

Software Developer

Hello - my name is Christian and I am 26 years old. I'm an educated Software Developer with a primary focus on C#, .NET Core, Python, and PowerShell. Currently, I'm expanding my skills in Software Robots and Cloud Architecture. In some of my spare time, I share my knowledge about tech stuff on my blog.

Recent articles

personal website

Top 6 things to add on your personal website to get hired for a tech job

domingo, agosto 7, 2022
watchdog

The #1 guide to show real-time .NET 6 logs for Web Apps and APIs in a modern way using WatchDog for Free

sábado, agosto 13, 2022
get hired for a tech job

5 tips to help you get hired for a tech job

domingo, julho 31, 2022
  • pt_BRPortuguês do Brasil
    • da_DKDansk
    • en_USEnglish
    • de_DEDeutsch
    • hi_INहिन्दी
  • Contact
  • Política de privacidade
  • Termos de serviço

© 2022 Christian Schou - All rights reserved.

No Result
View All Result
  • Casa
  • Blog
    • Programação
      • C#
      • PowerShell
      • Python
      • SQL
    • WordPress
      • Tutoriais
    • Nuvem
    • Automação residencial
      • Assistente Doméstico
    • Career
  • Serviços
  • Glossário
  • About

© 2022 Christian Schou - All rights reserved.

Eu uso cookies no meu site para lhe dar a experiência mais relevante, lembrando suas preferências e visitas repetidas. Ao clicar em “Aceitar”, você concorda com o uso de TODOS os cookies.
Não vender minhas informações pessoais.
Configurações de cookiesACCEPT
Política de Privacidade e Cookies

Visão geral da privacidade

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary
Sempre ativado
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Functional
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytics
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
CookieDuraçãoDescrição
__gads1 year 24 daysThe __gads cookie, set by Google, is stored under DoubleClick domain and tracks the number of times users see an advert, measures the success of the campaign and calculates its revenue. This cookie can only be read from the domain they are set on and will not track any data while browsing through other sites.
_ga2 yearsThe _ga cookie, installed by Google Analytics, calculates visitor, session and campaign data and also keeps track of site usage for the site's analytics report. The cookie stores information anonymously and assigns a randomly generated number to recognize unique visitors.
_ga_0J2F6JVWSD2 yearsThis cookie is installed by Google Analytics.
_gat_gtag_UA_84232734_11 minuteSet by Google to distinguish users.
_gid1 dayInstalled by Google Analytics, _gid cookie stores information on how visitors use a website, while also creating an analytics report of the website's performance. Some of the data that are collected include the number of visitors, their source, and the pages they visit anonymously.
YouTube2 yearsYouTube sets this cookie via embedded youtube-videos and registers anonymous statistical data. I embed YouTube videos in my articles/tutorials - you won't get the full experience of the articles if this is deactivated.
Advertisement
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
CookieDuraçãoDescrição
IDE1 year 24 daysGoogle DoubleClick IDE cookies are used to store information about how the user uses the website to present them with relevant ads and according to the user profile.
test_cookie15 minutesThe test_cookie is set by doubleclick.net and is used to determine if the user's browser supports cookies.
VISITOR_INFO1_LIVE5 months 27 daysA cookie set by YouTube to measure bandwidth that determines whether the user gets the new or old player interface.
YSCsessionYSC cookie is set by Youtube and is used to track the views of embedded videos on Youtube pages.
yt-remote-connected-devicesneverYouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
yt-remote-device-idneverYouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
Others
Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.
SALVAR E ACEITAR
Desenvolvido por CookieYes Logo