Skip to content

Authentication

FullstackCodingGuy edited this page Feb 24, 2025 · 7 revisions

Types of authentication

read image

[1.] 𝐀𝐏𝐈 𝐊𝐞𝐲𝐬 ◾ Simple, unique identifiers assigned to each client or service. ◾ Sent as a header or query parameter with each request. ◾ Best suited for internal services, less sensitive APIs, or for granting access to specific features. ◾ Easy to implement and manage. ◾ Not as secure as token-based methods. Keys can be easily leaked or stolen.

[2.] 𝐁𝐚𝐬𝐢𝐜 𝐀𝐮𝐭𝐡𝐞𝐧𝐭𝐢𝐜𝐚𝐭𝐢𝐨𝐧 ◾ Username and password are sent in the Authorization header as base64 encoded string. ◾ Simple to implement but requires HTTPS to be secure. ◾ Suitable for simple scenarios with low-security requirements. ◾ Widely supported and easy to understand. ◾ Vulnerable to man-in-the-middle attacks if not used with HTTPS. ◾ Passwords are sent in cleartext (even when encoded).

[3.] 𝐉𝐒𝐎𝐍 𝐖𝐞𝐛 𝐓𝐨𝐤𝐞𝐧𝐬 (𝐉𝐖𝐓) ◾ Self-contained tokens that carry user information and claims in a JSON payload. ◾ Issued by an authentication server after successful login, then sent by the client in the Authorization header. ◾ Widely used for stateless authentication in microservices, single sign-on (SSO) and authorization. ◾ Stateless, secure, compact and can contain additional claims. ◾ Requires proper key management for signing and verification.

[4.] 𝐎𝐀𝐮𝐭𝐡 2.0 ◾ An authorization framework allowing third-party applications to obtain limited access to resources on behalf of the resource owner (user) without sharing credentials. ◾ Uses various grant types (authorization code, implicit, client credentials, etc.) to obtain access tokens and refresh tokens. ◾ Widely used for user authorization and delegated access to APIs. ◾ Provides a standardized way to secure access to resources without sharing credentials. ◾ Can be complex to implement and requires careful consideration of security vulnerabilities.

[5.] 𝐎𝐩𝐞𝐧𝐈𝐃 𝐂𝐨𝐧𝐧𝐞𝐜𝐭 (𝐎𝐈𝐃𝐂) ◾ An identity layer on top of OAuth 2.0 that provides user authentication and profile information. ◾ Uses an ID token along with the access token to provide user identity information. ◾ Used for authentication in conjunction with OAuth 2.0 for authorization. ◾ Simplifies authentication by providing a standardized way to obtain user information. ◾ Requires integration with an OIDC provider (e.g., Google, Okta).

[6.] 𝐌𝐮𝐭𝐮𝐚𝐥 𝐓𝐋𝐒 (𝐦𝐓𝐋𝐒) ◾ Both client and server authenticate each other using X.509 certificates. ◾ Requires a certificate authority (CA) to issue and manage certificates. ◾ Best suited for securing communication between internal services or highly sensitive APIs. ◾ Strong security due to mutual authentication and encryption. ◾ More complex to set up and manage compared to other mechanisms.

JWT

JWT or JSON Web Tokens is an open standard for securely transmitting information between two parties. They are widely used for authentication and authorization.

A JWT consists of three main components:

1 - Header Every JWT carries a header specifying the algorithms for signing the JWT. It’s written in JSON format.

2 - Payload The payload consists of the claims and the user data. There are different types of claims such as registered, public, and private claims.

3 - Signature The signature is what makes the JWT secure. It is created by taking the encoded header, encoded payload, secret key, and the algorithm and signing it.

JWTs can be signed in two different ways:

1 - Symmetric Signatures It uses a single secret key for both signing the token and verifying it. The same key must be shared between the server that signs the JWT and the system that verifies it.

2 - Asymmetric Signatures In this case, a private key is used to sign the token, and a public key to verify it. The private key is kept secure on the server, while the public key can be distributed to anyone who needs to verify the token.

image
SAML vs OpenID Connect

🔑 Key Differences Between SAML and OIDC

Feature SAML (Security Assertion Markup Language) OIDC (OpenID Connect)
Protocol Type XML-based SSO authentication protocol JSON-based authentication layer over OAuth2
Underlying Standard Uses XML (Extensible Markup Language) Uses JSON (JavaScript Object Notation)
Authentication vs Authorization Primarily for authentication Used for authentication but built on OAuth2 (authorization)
Transport Mechanism Relies on HTTP POST (via browser redirects) Uses RESTful API calls (via tokens in HTTP headers)
Tokens Used SAML Assertions (XML format) JWT (JSON Web Token)
Best Suited For Enterprise apps, SSO for internal/corporate networks Web & mobile apps, APIs, microservices
IdP Communication Uses Service Provider (SP) & Identity Provider (IdP) Uses Client, Authorization Server, and Resource Server
Token Storage SAML Assertion is not stored; it is a one-time authentication response JWT is stored in the app (local storage, cookies) for re-authentication
Session Management Server-side (stateless) Can be both stateful or stateless
Mobile App Support Not ideal for mobile apps Designed for mobile-friendly authentication
Scalability Heavier due to XML parsing Lightweight & faster due to JSON
Use Cases Enterprise SSO (Okta, AD FS, PingFederate) Web, API authentication (Google, Microsoft, AWS Cognito)

📌 When to Use SAML vs. OIDC?

  • Use SAML when:

    • You need Single Sign-On (SSO) for corporate/enterprise applications.
    • Your organization already uses Active Directory Federation Services (AD FS), Okta, or PingFederate.
    • You're dealing with legacy applications that rely on XML-based authentication.
  • Use OIDC when:

    • You are building a modern web or mobile application.
    • You need an API-driven authentication system (e.g., microservices, REST APIs).
    • You want a lightweight, JSON-based protocol with better support for mobile and cloud-based applications.

🚀 Summary

  • SAML is better for enterprise SSO with existing identity providers.
  • OIDC is better for modern applications that need API-driven authentication.
  • OIDC is more flexible, scalable, and mobile-friendly than SAML.

Would you like help implementing OIDC authentication in your .NET API? 🚀

Session based Vs JWT based

Think of session-based authentication like a boarding pass ID at an airport. The system keeps the details about your session in a secure store, and you’re given a session ID to use.

How It Works:

  1. The user logs in, and their credentials are validated by the server.
  2. The server creates a session with all user details and stores it in a session store (database or memory).
  3. A session ID is sent back to the client as a cookie.
  4. On every subsequent request, the browser sends the session ID cookie to the server.
  5. The server checks the session store for the ID to verify the user.

Pros:

  • Easy to invalidate sessions (just remove them from the store).
  • Familiar and simple for server-side apps.

Cons:

  • Not ideal for distributed systems (requires shared session storage).
  • Can become a bottleneck as the user base grows.

Imagine JWTs as your boarding pass with all flight details printed on it, but encrypted and signed. The server doesn’t need to store anything because the token itself holds all necessary data.

How It Works:

  1. The user logs in, and their credentials are validated by the server.
  2. The server generates a JWT containing user data (e.g., user ID, roles) and signs it with a secret key.
  3. The JWT is sent back to the client as a cookie or header.
  4. On subsequent requests, the browser sends the JWT.
  5. The server verifies the JWT using the secret key and extracts user data.

Pros:

  • Stateless: No server-side storage required.
  • Ideal for distributed systems and scaling.
  • Works well with microservices and client-side rendering.

Cons:

  • Revoking JWTs is difficult (you can’t just delete them).
  • Tokens can become stale if user permissions or roles change.
  • Larger payloads can slow down requests.

Session vs. JWTs: When to Use What?

Session-Based Authentication:

  • Centralized server architecture.
  • Easier to manage for small to medium-scale projects.
  • Applications where sessions need to be invalidated quickly (e.g., financial apps).

JWT-Based Authentication:

  • Distributed systems or microservices architecture.
  • When scalability is a priority.
  • Applications with APIs accessed by multiple clients (e.g., mobile and web apps).

Implementing Keycloak in a .NET 9 API Solution

read

🔐 Implementing Keycloak in a .NET 9 API Solution

Keycloak is an open-source Identity Provider (IdP) supporting OAuth2, OpenID Connect (OIDC), and SAML. Below are the steps to integrate Keycloak authentication into your .NET 9 API.


🛠️ Step 1: Run Keycloak Locally

First, you need to run Keycloak on your machine.

Option 1: Run Keycloak with Docker

docker run -p 8080:8080 \
  -e KEYCLOAK_ADMIN=admin \
  -e KEYCLOAK_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak start-dev

Option 2: Manual Installation

  1. Download Keycloak from: https://www.keycloak.org/downloads
  2. Extract and navigate to the Keycloak folder.
  3. Start Keycloak in development mode:
    bin/kc.sh start-dev

🛠️ Step 2: Create a Realm & Client in Keycloak

Now, configure Keycloak:

1️⃣ Login to Keycloak

2️⃣ Create a Realm

  • Click "Create Realm" → Enter "MyRealm" → Save.

3️⃣ Create a Client for .NET API

  • Go to "Clients" → Create a new client.
  • Client ID: "my-dotnet-api"
  • Client Type: "OpenID Connect"
  • Root URL: http://localhost:5000/ (Your API URL)
  • Save.

4️⃣ Configure Client Credentials

  • Under the "Credentials" tab, copy the Client Secret.
  • Under "Settings", enable:
    • "Client authentication" → ON
    • "Service accounts roles" → ON

5️⃣ Create a User

  • Go to "Users" → Click "Create".
  • Username: testuser
  • Email: test@example.com
  • Set Password: (Under the "Credentials" tab)

🛠️ Step 3: Configure .NET 9 API to Use Keycloak

Now, modify your .NET 9 API to support authentication.

1️⃣ Install Required Packages

Run the following command:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

2️⃣ Configure Authentication in Program.cs

Modify your Program.cs to use JWT Bearer Authentication:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

var builder = WebApplication.CreateBuilder(args);

// Add Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "http://localhost:8080/realms/MyRealm";
        options.Audience = "my-dotnet-api"; // Must match the Keycloak Client ID
        options.RequireHttpsMetadata = false; // Disable in development
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true
        };
    });

// Add Authorization
builder.Services.AddAuthorization();

var app = builder.Build();

app.UseAuthentication(); // Apply Authentication Middleware
app.UseAuthorization();

app.MapGet("/secure", () => "You are authenticated!")
    .RequireAuthorization(); // Protect this endpoint

app.Run();

🛠️ Step 4: Test Authentication

Now, test the authentication using Postman or cURL.

1️⃣ Get a Token from Keycloak

Using cURL

curl -X POST "http://localhost:8080/realms/MyRealm/protocol/openid-connect/token" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "client_id=my-dotnet-api" \
     -d "grant_type=password" \
     -d "username=testuser" \
     -d "password=yourpassword"

Using Postman

  • POST: http://localhost:8080/realms/MyRealm/protocol/openid-connect/token
  • Body (x-www-form-urlencoded):
    • client_id=my-dotnet-api
    • grant_type=password
    • username=testuser
    • password=yourpassword

Response:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expires_in": 300,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer"
}

🛠️ Step 5: Access a Protected API Endpoint

Now, call the secure API endpoint using the token.

curl -X GET "http://localhost:5000/secure" \
     -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

If the token is valid, you'll receive:

"You are authenticated!"

Otherwise, you'll get:

"401 Unauthorized"

🎯 Bonus: Role-Based Authorization

To restrict access based on roles, update Program.cs:

app.MapGet("/admin", () => "Welcome Admin!")
    .RequireAuthorization(policy => policy.RequireRole("admin"));

Then, assign the "admin" role to your Keycloak user.


📌 Summary

  1. Run Keycloak using Docker.
  2. Create a Realm & Client in Keycloak.
  3. Configure .NET API to authenticate using Keycloak.
  4. Obtain an Access Token and test authentication.
  5. Secure API Endpoints with role-based authorization.

🚀 Next Steps

  • ✅ Implement Role-Based Authorization.
  • ✅ Configure API Gateway Authentication.
  • ✅ Deploy Keycloak on Kubernetes for production.

Would you like help with Keycloak integration in Angular/React frontend? 🚀

Scope in Token based Authentication

read

Scope in Token Generation

In token-based authentication (such as OAuth 2.0 and OpenID Connect), scope is a mechanism for defining permissions or access levels that a client application has when requesting an access token.


Why is Scope Important?

  1. Restricts Access → Ensures tokens grant access to only specific resources, enhancing security.
  2. Minimizes Privileges → Implements least privilege by preventing over-permissioned tokens.
  3. Improves API Security → API endpoints check token scopes before granting access.
  4. Allows Granular Authorization → Different clients (e.g., mobile apps vs. web apps) can get different permissions.

How Scope Works in OAuth 2.0

  1. Client Requests a Token with Specific Scopes

    • Example request in OAuth 2.0:
    POST /oauth/token HTTP/1.1
    Host: authserver.com
    Content-Type: application/x-www-form-urlencoded
    

    grant_type=client_credentials &client_id=your_client_id &client_secret=your_client_secret &scope=read:users write:users

  2. Authorization Server Validates & Issues a Token with Granted Scopes

    • The Access Token contains allowed scopes (e.g., read:users).
  3. Resource Server (API) Checks the Scope

    • API endpoints validate whether the token has the required scope before allowing access.

Example of Scope Usage in a JWT Token

A JSON Web Token (JWT) with scopes might look like this:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1616882223,
  "exp": 1616885823,
  "scope": "read:users write:users"
}

Example: Enforcing Scope in C# ASP.NET Core

In ASP.NET Core, you can validate scopes using policy-based authorization.

Step 1: Add Authentication & Scope Policy in Program.cs

builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer(options =>
    {
        options.Authority = "https://authserver.com";
        options.Audience = "my-api";
    });

builder.Services.AddAuthorization(options => { options.AddPolicy("ReadUsers", policy => policy.RequireClaim("scope", "read:users")); });


Step 2: Apply Scope to API Endpoints

[Authorize(Policy = "ReadUsers")]
[HttpGet("users")]
public IActionResult GetUsers()
{
    return Ok(new { message = "User data accessed!" });
}
  • If the token does not contain the read:users scope, access is denied (403 Forbidden).

Common Scope Examples

Scope Description
read:users Read user information
write:users Create/update users
delete:users Delete users
read:messages Read messages
write:messages Send messages

Key Takeaways

Scope defines what an access token can do (limits permissions).
APIs should enforce scope validation to enhance security.
Use policies in ASP.NET Core to check token claims.
Follow the principle of least privilege (don’t over-assign permissions).

Would you like a deeper dive into scope validation in an OAuth 2.0 provider like IdentityServer or Auth0? 🚀

Clone this wiki locally