Identity Server 4 Grant Types
Before get into the code snippets, we need to understand the grant types of application authorization.
The grant types defined in IdentityServer4 is:
Many of them are not recommended to use in any project due security reasons, mainly that is very susceptible to attacks.
So in this article we will cover only what is more "safe" to use, and is only the client credentials and authorization code, it is acceptable the refresh tokens with some remarks, but I'll not cover in this article, if you want this to be cover, let a comment.
Client credentials
This is the simplest grant type and is used for server to server communication - tokens are always requested on behalf of a client, not a user.
With this grant type you send a token request to the token endpoint, and get an access token back that represents the client. The client typically has to authenticate with the token endpoint using its client ID and secret.
So we can use this when we have control in the network level, inside a Kubernetes cluster for example.
So this is when an Web App need to call an API for example.
Authorization code
This flow is ideal for server-side applications that require secure handling of user credentials. It starts when a user attempts to log in to a client application. The client redirects the user to an authorization server, where they log in and grant the necessary permissions.
The flow is illustrated with image below:
领英推荐
It's important to note that, usually this flow is integrated with PKCE (Proof Key for Code Exchange) that is a security extension that is designed to prevent code injection attacks. In the PKCE flow, the client generates a random code verifier and transforms it into a code challenge that is sent to the Authorization Server. The Authorization Server uses the code challenge to validate the authorization code.
These are the only flows that are still recommended to use, note that these are Access Token and it's not bounded to a client, so anyone with access to these token will be able to access the protected resource, today we also have Proof-of-Possession (PoP) tokens are bound to the client that requested the token. This is also often called sender constraining. This is done by using cryptography to prove that the sender of the token knows an additional secret only known to the client. But this is not supported by the version of library in use in this article.
Reference Tokens
This is not a grant type, but I think it's important to mention.
One important detail here is that, in a micro services ecosystem, it's easy one service need to call many other services, and there is a limitation on the size of the token, one option that you have is to use reference tokens.
Here are some advantages of the Reference Tokens:
The main disadvantage is that each time you need to verify the token, need to have a extra call to the Identity Service provider.
Refresh Token
This is also not related to the grant type, but is also important aspect that need to be known.
A refresh token is a credential used to obtain new access tokens without requiring the user to re-authenticate. Unlike access tokens, which are short-lived for security reasons, refresh tokens are typically long-lived and allow the client to maintain access to protected resources even after the original access token expires. This grant type is particularly useful in scenarios where the application needs to maintain user sessions over extended periods, such as in mobile apps or long-running background services. By exchanging the refresh token for a new access token, the user’s credentials remain secure, and the risk of token leakage is minimized.
However, refresh tokens also introduce certain security concerns. If a refresh token is stolen or compromised, an attacker could gain long-term access to the system. To mitigate this risk, Identity Server and OAuth implementations often recommend using refresh token rotation, where a new refresh token is issued each time a new access token is requested, invalidating the old refresh token. Additionally, it's essential to store refresh tokens securely, use HTTPS for all communication, and implement strict expiration policies and scopes to limit the damage in case of token compromise. Properly handling refresh tokens is crucial for ensuring both security and a seamless user experience in modern applications.
This is all for now in theses series, if you want me to cover anything leave a comment! You can check the previous article here.