Introduction to OAuth 2.0 and JWT in C#
\nModern web applications require robust security mechanisms. Two key protocols — OAuth 2.0 and JWT (JSON Web Token) — have become the de facto standard for implementing authorization and authentication. In this article, we will explore how to use these technologies in the C# (.NET) ecosystem.
\nOAuth 2.0 is a delegated access protocol that allows applications to obtain limited access to user resources without sharing their credentials. JWT, in turn, is a compact and self-contained token format often used to transmit authentication information between a client and a server.
\nIn this guide, we will create a simple web API in ASP.NET Core that implements OAuth 2.0 using JWT tokens. You will learn how to configure token generation, validation, and endpoint protection.
\n\nWhat are OAuth 2.0 and JWT?
\nBefore diving into the code, let's review the core concepts.
\nOAuth 2.0
\nOAuth 2.0 defines four roles:
\n- \n
- Resource Owner — typically the user. \n
- Client — the application requesting access. \n
- Authorization Server — issues tokens. \n
- Resource Server — serves protected data. \n
The main Authorization Code Grant flow includes: redirecting the user to the authorization server, obtaining a code, and exchanging the code for an access token.
\n\nJWT (JSON Web Token)
\nA JWT consists of three parts separated by dots:
\n- \n
- Header — token type and signing algorithm (e.g., HS256). \n
- Payload — data (claims) such as user ID, role, expiration time. \n
- Signature — a signature created using a secret key. \n
Example JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Setting Up the ASP.NET Core Project
\nLet's create a new web API project with authentication support.
\ndotnet new webapi -n OAuthJwtDemo\ncd OAuthJwtDemo\nAdd the required NuGet packages:
\ndotnet add package Microsoft.AspNetCore.Authentication.JwtBearer\ndotnet add package System.IdentityModel.Tokens.Jwt\n\nConfiguration in appsettings.json
\nAdd a section for JWT settings in the appsettings.json file:
{\n "JwtSettings": {\n "SecretKey": "YOUR_SUPER_SECRET_KEY_AT_LEAST_32_CHARS",\n "Issuer": "OAuthJwtDemo",\n "Audience": "OAuthJwtDemoClient",\n "ExpirationMinutes": 60\n }\n}\nImportant: In a real project, store the secret key in User Secrets or Azure Key Vault.
\n\nImplementing the JWT Generation Service
\nCreate an interface and its implementation for working with tokens.
\nIJwtService Interface
\npublic interface IJwtService\n{\n string GenerateToken(string userId, string role);\n ClaimsPrincipal ValidateToken(string token);\n}\n\nJwtService Implementation
\npublic class JwtService : IJwtService\n{\n private readonly JwtSettings _settings;\n\n public JwtService(IOptions<JwtSettings> settings)\n {\n _settings = settings.Value;\n }\n\n public string GenerateToken(string userId, string role)\n {\n var claims = new[]\n {\n new Claim(ClaimTypes.NameIdentifier, userId),\n new Claim(ClaimTypes.Role, role),\n new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())\n };\n\n var key = new Symmetric