♻️ Refactor OpenID: Phase 2: Security Hardening - PKCE Implementation

- Added GenerateCodeVerifier() and GenerateCodeChallenge() methods to base OidcService
- Implemented PKCE (Proof Key for Code Exchange) for Google OAuth flow:
  * Generate cryptographically secure code verifier (256-bit random)
  * Create SHA-256 code challenge for authorization request
  * Cache code verifier with 15-minute expiration for token exchange
  * Validate and remove code verifier during callback to prevent replay attacks
- Enhances security by protecting against authorization code interception attacks
- Uses S256 (SHA-256) code challenge method as per RFC 7636
This commit is contained in:
2025-11-02 14:55:15 +08:00
parent 4bd59f107b
commit 74a9ca98ad
2 changed files with 60 additions and 4 deletions

View File

@@ -1,4 +1,7 @@
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json.Serialization;
using DysonNetwork.Shared.Cache;
using DysonNetwork.Shared.Models;
@@ -84,6 +87,38 @@ public abstract class OidcService(
};
}
/// <summary>
/// Generates a cryptographically secure random code verifier for PKCE
/// </summary>
protected static string GenerateCodeVerifier()
{
// Generate a 32-byte (256-bit) random byte array
var randomBytes = new byte[32];
RandomNumberGenerator.Fill(randomBytes);
// Convert to URL-safe base64 (no padding)
return Convert.ToBase64String(randomBytes)
.Replace("+", "-")
.Replace("/", "_")
.TrimEnd('=');
}
/// <summary>
/// Generates the code challenge from a code verifier using S256 method
/// </summary>
protected static string GenerateCodeChallenge(string codeVerifier)
{
using var sha256 = SHA256.Create();
var bytes = Encoding.UTF8.GetBytes(codeVerifier);
var hash = sha256.ComputeHash(bytes);
// Convert to URL-safe base64 (no padding)
return Convert.ToBase64String(hash)
.Replace("+", "-")
.Replace("/", "_")
.TrimEnd('=');
}
/// <summary>
/// Retrieves the OpenID Connect discovery document
/// </summary>