Rystem.Authentication.Social
10.0.3
dotnet add package Rystem.Authentication.Social --version 10.0.3
NuGet\Install-Package Rystem.Authentication.Social -Version 10.0.3
<PackageReference Include="Rystem.Authentication.Social" Version="10.0.3" />
<PackageVersion Include="Rystem.Authentication.Social" Version="10.0.3" />
<PackageReference Include="Rystem.Authentication.Social" />
paket add Rystem.Authentication.Social --version 10.0.3
#r "nuget: Rystem.Authentication.Social, 10.0.3"
#:package Rystem.Authentication.Social@10.0.3
#addin nuget:?package=Rystem.Authentication.Social&version=10.0.3
#tool nuget:?package=Rystem.Authentication.Social&version=10.0.3
What is Rystem?
📚 Resources
- 📖 Complete Documentation: https://rystem.net
- 🤖 MCP Server for AI: https://rystem.cloud/mcp
- 💬 Discord Community: https://discord.gg/tkWvy4WPjt
- ☕ Support the Project: https://www.buymeacoffee.com/keyserdsoze
Rystem.Authentication.Social
Server-side social authentication library for .NET that provides OAuth 2.0 integration with multiple providers (Microsoft, Google, Facebook, GitHub, Amazon, LinkedIn, X/Twitter, TikTok, Instagram, Pinterest).
✨ Key Features
- 🔐 PKCE Support: Implements RFC 7636 Proof Key for Code Exchange for enhanced security
- 🌐 Multiple Providers: Support for 10+ OAuth providers
- 🎯 Token Management: Built-in bearer and refresh token handling
- 🔧 Extensible: Custom user providers and claim management
- ⚡ Modern APIs: Minimal API endpoints with automatic OpenAPI documentation
📦 Installation
dotnet add package Rystem.Authentication.Social
🚀 Quick Start
1. Configure Services
builder.Services.AddSocialLogin(x =>
{
// Configure OAuth providers
x.Microsoft.ClientId = builder.Configuration["SocialLogin:Microsoft:ClientId"];
x.Microsoft.ClientSecret = builder.Configuration["SocialLogin:Microsoft:ClientSecret"];
x.Microsoft.RedirectDomain = builder.Configuration["SocialLogin:Microsoft:RedirectDomain"];
x.Google.ClientId = builder.Configuration["SocialLogin:Google:ClientId"];
x.Google.ClientSecret = builder.Configuration["SocialLogin:Google:ClientSecret"];
x.Google.RedirectDomain = builder.Configuration["SocialLogin:Google:RedirectDomain"];
x.Facebook.ClientId = builder.Configuration["SocialLogin:Facebook:ClientId"];
x.Facebook.ClientSecret = builder.Configuration["SocialLogin:Facebook:ClientSecret"];
x.Facebook.RedirectDomain = builder.Configuration["SocialLogin:Facebook:RedirectDomain"];
// Add other providers as needed (GitHub, Amazon, LinkedIn, X, TikTok, Instagram, Pinterest)
},
x =>
{
// Configure token expiration
x.BearerTokenExpiration = TimeSpan.FromHours(1);
x.RefreshTokenExpiration = TimeSpan.FromDays(10);
});
2. Register Endpoints
app.UseSocialLoginEndpoints();
This registers the following endpoints:
POST /api/Authentication/Social/Token- Exchange OAuth code for JWT token (with PKCE support)GET /api/Authentication/Social/Token- Legacy endpoint (backward compatibility)GET /api/Authentication/Social/User- Get authenticated user information
3. Custom User Provider
builder.Services.AddSocialUserProvider<SocialUserProvider>();
Implement ISocialUserProvider to integrate with your database:
internal sealed class SocialUserProvider : ISocialUserProvider
{
private readonly IRepository<User> _userRepository;
public SocialUserProvider(IRepository<User> userRepository)
{
_userRepository = userRepository;
}
public async Task<SocialUser> GetAsync(string username, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
// Fetch user from your database
var user = await _userRepository.Query()
.Where(x => x.Email == username)
.FirstOrDefaultAsync(cancellationToken);
if (user == null)
{
// Create new user on first login
user = new User
{
Email = username,
Name = claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value
};
await _userRepository.InsertAsync(user, cancellationToken);
}
return new CustomSocialUser
{
Username = user.Email,
DisplayName = user.Name,
UserId = user.Id
};
}
public async IAsyncEnumerable<Claim> GetClaimsAsync(string? username, CancellationToken cancellationToken)
{
var user = await _userRepository.Query()
.Where(x => x.Email == username)
.FirstOrDefaultAsync(cancellationToken);
if (user != null)
{
yield return new Claim(ClaimTypes.NameIdentifier, user.Id.ToString());
yield return new Claim(ClaimTypes.Name, user.Name);
yield return new Claim(ClaimTypes.Email, user.Email);
yield return new Claim(ClaimTypes.Role, user.Role);
}
}
}
public sealed class CustomSocialUser : DefaultSocialUser
{
public string DisplayName { get; set; }
public Guid UserId { get; set; }
}
🔐 PKCE (Proof Key for Code Exchange)
What is PKCE?
PKCE (RFC 7636) enhances OAuth 2.0 security by preventing authorization code interception attacks. It's required for:
- Single-Page Applications (SPAs)
- Mobile applications
- Public clients (where client secrets cannot be safely stored)
How PKCE Works
- Client generates
code_verifier: Random 43-128 character string - Client creates
code_challenge: SHA256 hash of code_verifier, base64url encoded - Authorization request: Client sends
code_challengeto OAuth provider - Token exchange: Client sends original
code_verifierto your API - API validates: Verifies code_verifier matches code_challenge with OAuth provider
PKCE Implementation
The library automatically handles PKCE when clients send code_verifier:
// Endpoint accepts code_verifier in request body
POST /api/Authentication/Social/Token?provider=Microsoft&code={oauth_code}&redirectPath=/account/login
Content-Type: application/json
{
"code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
}
The TokenCheckerSettings class encapsulates all parameters:
public sealed class TokenCheckerSettings
{
public string? Domain { get; set; } // OAuth redirect domain
public string RedirectPath { get; set; } = "/"; // Redirect path (for exact URI matching)
public Dictionary<string, string>? AdditionalParameters { get; set; } // Includes code_verifier for PKCE
public string GetRedirectUri() => $"{Domain.TrimEnd('/')}{RedirectPath}";
public string? GetParameter(string key) => AdditionalParameters?.TryGetValue(key, out var val) == true ? val : null;
}
Backward Compatibility
If code_verifier is not provided, the library falls back to a default value for backward compatibility:
// Legacy GET request (no PKCE)
GET /api/Authentication/Social/Token?provider=Microsoft&code={oauth_code}
⚠️ Security Note: For production SPAs and mobile apps, always use PKCE.
🎯 Token Checker Interface
All OAuth providers implement ITokenChecker:
public interface ITokenChecker
{
Task<AnyOf<TokenResponse?, string>> CheckTokenAndGetUsernameAsync(
string code,
TokenCheckerSettings settings,
CancellationToken cancellationToken = default);
}
Supported Providers
| Provider | PKCE Support | Token Checker |
|---|---|---|
| Microsoft | ✅ Required | MicrosoftTokenChecker |
| ✅ Optional | GoogleTokenChecker |
|
| GitHub | ❌ Not supported | GithubTokenChecker |
| ❌ Not supported | FacebookTokenChecker |
|
| Amazon | ❌ Not supported | AmazonTokenChecker |
| ❌ Not supported | LinkedinTokenChecker |
|
| X (Twitter) | ❌ Not supported | XTokenChecker |
| TikTok | ❌ Not supported | TikTokTokenChecker |
| ❌ Not supported | InstagramTokenChecker |
|
| ❌ Not supported | PinterestTokenChecker |
📝 Configuration Example
appsettings.json
{
"SocialLogin": {
"Microsoft": {
"ClientId": "your-microsoft-client-id",
"ClientSecret": "your-microsoft-client-secret",
"RedirectDomain": "https://yourdomain.com"
},
"Google": {
"ClientId": "your-google-client-id",
"ClientSecret": "your-google-client-secret",
"RedirectDomain": "https://yourdomain.com"
}
}
}
OAuth Provider Setup
Microsoft Entra ID (Azure AD)
- Go to Azure Portal → Azure Active Directory → App registrations
- Create new registration, set redirect URI:
https://yourdomain.com/account/login - Enable "ID tokens" under Authentication
- Copy Application (client) ID and create a client secret
- Go to Google Cloud Console → APIs & Services → Credentials
- Create OAuth 2.0 Client ID
- Add authorized redirect URI:
https://yourdomain.com/account/login - Copy Client ID and Client Secret
- Go to Facebook Developers → My Apps → Create App
- Add Facebook Login product
- Set Valid OAuth Redirect URI:
https://yourdomain.com/account/login - Copy App ID and App Secret
🔧 Advanced Configuration
Custom Token Validation
Implement custom ITokenChecker for additional providers:
public class CustomTokenChecker : ITokenChecker
{
public async Task<AnyOf<TokenResponse?, string>> CheckTokenAndGetUsernameAsync(
string code,
TokenCheckerSettings settings,
CancellationToken cancellationToken)
{
var codeVerifier = settings.GetParameter("code_verifier");
var redirectUri = settings.GetRedirectUri();
// Your custom OAuth token exchange logic
// ...
return new TokenResponse
{
Username = "user@example.com",
Claims = new List<Claim>
{
new Claim(ClaimTypes.Email, "user@example.com")
}
};
}
}
Custom Claim Transformation
public async IAsyncEnumerable<Claim> GetClaimsAsync(string? username, CancellationToken cancellationToken)
{
// Add custom claims based on user roles from database
var userRoles = await _roleRepository.GetUserRolesAsync(username, cancellationToken);
foreach (var role in userRoles)
{
yield return new Claim(ClaimTypes.Role, role.Name);
}
// Add custom application-specific claims
yield return new Claim("tenant_id", "tenant-123");
yield return new Claim("subscription_level", "premium");
}
🌐 API Endpoints Reference
POST /api/Authentication/Social/Token
Query Parameters:
provider(required): OAuth provider (Microsoft, Google, Facebook, etc.)code(required): Authorization code from OAuth providerredirectPath(optional): OAuth redirect path (default:/)
Request Body (JSON):
{
"code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
}
Response (200 OK):
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "refresh-token-here",
"expiresIn": 3600
}
GET /api/Authentication/Social/User
Headers:
Authorization: Bearer {accessToken}
Response (200 OK):
{
"username": "user@example.com",
"displayName": "John Doe",
"userId": "guid-here"
}
🔗 Related Packages
- Blazor Client:
Rystem.Authentication.Social.Blazor- UI components for Blazor Server/WASM - React Client:
rystem.authentication.social.react- React hooks and components with TypeScript - Abstractions:
Rystem.Authentication.Social.Abstractions- Shared models and interfaces
📚 More Information
- Complete Docs: https://rystem.net/mcp/tools/auth-social-server.md
- PKCE RFC: RFC 7636
- OAuth 2.0 Flow: https://rystem.net/mcp/prompts/auth-flow.md
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Google.Apis.Auth (>= 1.73.0)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.15.0)
- Microsoft.IdentityModel.Tokens (>= 8.15.0)
- Rystem.Authentication.Social.Abstractions (>= 10.0.3)
- Rystem.DependencyInjection (>= 10.0.3)
- System.IdentityModel.Tokens.Jwt (>= 8.15.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.0.3 | 61 | 1/28/2026 |
| 10.0.1 | 173,847 | 11/12/2025 |
| 9.1.3 | 284 | 9/2/2025 |
| 9.1.2 | 764,464 | 5/29/2025 |
| 9.1.1 | 97,826 | 5/2/2025 |
| 9.0.33 | 232 | 4/30/2025 |
| 9.0.32 | 186,714 | 4/15/2025 |
| 9.0.31 | 5,839 | 4/2/2025 |
| 9.0.30 | 88,831 | 3/26/2025 |
| 9.0.29 | 9,003 | 3/18/2025 |
| 9.0.28 | 225 | 3/17/2025 |
| 9.0.27 | 236 | 3/16/2025 |
| 9.0.26 | 254 | 3/13/2025 |
| 9.0.25 | 52,134 | 3/9/2025 |
| 9.0.21 | 361 | 3/6/2025 |
| 9.0.20 | 19,566 | 3/6/2025 |
| 9.0.19 | 291 | 3/6/2025 |
| 9.0.18 | 284 | 3/4/2025 |
| 9.0.17 | 201 | 3/1/2025 |
| 9.0.16 | 189 | 3/1/2025 |
| 9.0.15 | 75,508 | 2/22/2025 |
| 9.0.14 | 22,563 | 2/18/2025 |
| 9.0.13 | 194 | 2/9/2025 |
| 9.0.12 | 217,710 | 1/13/2025 |
| 9.0.11 | 24,026 | 1/9/2025 |
| 9.0.10 | 143 | 1/9/2025 |
| 9.0.9 | 4,031 | 1/7/2025 |
| 9.0.8 | 12,523 | 1/6/2025 |
| 9.0.7 | 202 | 1/6/2025 |
| 9.0.4 | 92,301 | 12/23/2024 |
| 9.0.3 | 177 | 12/22/2024 |
| 9.0.2 | 10,730 | 12/21/2024 |
| 9.0.1 | 1,226 | 12/21/2024 |
| 9.0.0 | 173,106 | 11/16/2024 |
| 9.0.0-rc.1 | 130 | 10/18/2024 |
| 6.2.0 | 219,126 | 10/9/2024 |
| 6.1.1 | 192 | 10/9/2024 |
| 6.1.0 | 48,001 | 9/29/2024 |
| 6.0.24 | 236 | 9/11/2024 |
| 6.0.23 | 340,116 | 7/18/2024 |
| 6.0.21 | 211 | 6/18/2024 |
| 6.0.20 | 727,850 | 6/16/2024 |
| 6.0.19 | 30,446 | 6/14/2024 |
| 6.0.18 | 193 | 6/14/2024 |
| 6.0.17 | 212 | 6/14/2024 |
| 6.0.16 | 50,076 | 6/10/2024 |
| 6.0.15 | 197 | 6/9/2024 |
| 6.0.14 | 94,340 | 5/24/2024 |
| 6.0.13 | 221 | 5/23/2024 |
| 6.0.12 | 190 | 5/23/2024 |
| 6.0.11 | 213 | 5/20/2024 |
| 6.0.9 | 225 | 5/20/2024 |
| 6.0.7 | 226 | 5/18/2024 |
| 6.0.6 | 196 | 5/10/2024 |
| 6.0.5 | 182 | 5/10/2024 |
| 6.0.4 | 549,814 | 4/3/2024 |
| 6.0.3 | 257 | 3/25/2024 |
| 6.0.2 | 273 | 3/11/2024 |
| 6.0.1 | 301 | 3/8/2024 |
| 6.0.0 | 574 | 11/21/2023 |
| 6.0.0-rc.6 | 120 | 11/9/2023 |