-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Welcome to the SocialiteNET documentation. This wiki contains comprehensive information about the library, its features, and how to use it effectively in your ASP.NET Core applications.
- Introduction
- Installation
- Configuration
- Basic Usage
- Advanced Usage
- Providers
- Customization
- Examples
- Troubleshooting
- Contributing
SocialiteNET is an OAuth authentication wrapper for ASP.NET Core. It provides a clean, fluent API to handle the complex OAuth authentication process with minimal boilerplate code.
- .NET 8.0 or higher
- ASP.NET Core project
Install the SocialiteNET package using the .NET CLI:
dotnet add package SocialiteNETFirst, register Socialite services in your Program.cs or Startup.cs file:
using SocialiteNET;
var builder = WebApplication.CreateBuilder(args);
// Add Socialite services
builder.Services.AddSocialite(options =>
{
// Optional: Set a default provider
options.DefaultDriver = "google";
});
// Register required providers
builder.Services.AddSocialite()
.AddGoogle(options =>
{
options.ClientId = builder.Configuration["Authentication:Google:ClientId"];
options.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];
options.RedirectUrl = builder.Configuration["Authentication:Google:RedirectUrl"];
// Optional settings
// options.Stateless = true;
// options.UsesPkce = true;
// options.Scopes.Add("calendar");
});
var app = builder.Build();
// Add Socialite middleware (adds session and authentication)
app.UseSocialite();
// Other middleware configurations...Store your OAuth credentials in your configuration:
{
"Authentication": {
"Google": {
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"RedirectUrl": "https://your-app.com/auth/google/callback"
}
}
}Each provider can be configured with the following options:
| Option | Description | Default |
|---|---|---|
| ClientId | OAuth client ID | Required |
| ClientSecret | OAuth client secret | Required |
| RedirectUrl | Callback URL after authentication | Required |
| Scopes | List of OAuth scopes to request | Provider-specific defaults |
| ScopeSeparator | Character used to separate scopes | " " (space) |
| Stateless | Whether to operate in stateless mode | false |
| UsesPkce | Whether to use PKCE | false |
| Parameters | Additional OAuth parameters | {} |
The typical OAuth flow involves two routes:
- A route to redirect the user to the OAuth provider
- A callback route to handle the OAuth response
using Microsoft.AspNetCore.Mvc;
using SocialiteNET.Abstractions;
public class AuthController : Controller
{
private readonly ISocialite _socialite;
public AuthController(ISocialite socialite)
{
_socialite = socialite;
}
[HttpGet("auth/google")]
public async Task<IActionResult> RedirectToGoogle()
{
// Get the provider and generate the redirect URL
string redirectUrl = await _socialite.GetProvider("google")
.RedirectAsync(HttpContext);
// Redirect the user to the OAuth provider
return Redirect(redirectUrl);
}
[HttpGet("auth/google/callback")]
public async Task<IActionResult> HandleGoogleCallback()
{
// Get the authenticated user from the OAuth provider
IUser user = await _socialite.GetProvider("google")
.GetUserAsync(HttpContext);
// Process user information
// 1. Check if the user exists in your database
// 2. Create or update the user record
// 3. Sign in the user
// Available user properties
string id = user.Id; // Unique provider user ID
string? name = user.Name; // Full name
string? email = user.Email; // Email address
string? nickname = user.Nickname; // Username or nickname
string? avatar = user.Avatar; // Profile picture URL
string token = user.Token; // OAuth access token
string? refreshToken = user.RefreshToken; // OAuth refresh token (if available)
int expiresIn = user.ExpiresIn; // Token expiration in seconds
// Sign in the user with your auth system
// ...
return RedirectToAction("Dashboard", "Home");
}
}For APIs or applications without sessions, use stateless mode to skip state parameter validation:
// Configure at registration time
builder.Services.AddSocialite()
.AddGoogle(options =>
{
// ...
options.Stateless = true;
});
// Or at runtime
string redirectUrl = await _socialite.GetProvider("google")
.Stateless()
.RedirectAsync(HttpContext);For public clients (like SPAs), enable PKCE (Proof Key for Code Exchange) for enhanced security:
// Configure at registration time
builder.Services.AddSocialite()
.AddGoogle(options =>
{
// ...
options.UsesPkce = true;
});
// Or at runtime
string redirectUrl = await _socialite.GetProvider("google")
.WithPkce()
.RedirectAsync(HttpContext);Control exactly what permissions your application requests:
// Add specific scopes
string redirectUrl = await _socialite.GetProvider("google")
.AddScopes("calendar", "drive.readonly")
.RedirectAsync(HttpContext);
// Replace all scopes
string redirectUrl = await _socialite.GetProvider("google")
.SetScopes("email", "profile", "calendar")
.RedirectAsync(HttpContext);Add provider-specific parameters to the OAuth request:
// For Google: request a specific prompt behavior and access type
string redirectUrl = await _socialite.GetProvider("google")
.With(new {
prompt = "select_account",
access_type = "offline",
hd = "example.com"
})
.RedirectAsync(HttpContext);If you already have a valid access token, you can retrieve user information directly:
IUser user = await _socialite.GetProvider("google")
.GetUserFromTokenAsync(accessToken);For providers that support refresh tokens, you can obtain a new access token when it expires:
IToken newToken = await _socialite.GetProvider("google")
.RefreshTokenAsync(refreshToken);
string newAccessToken = newToken.AccessToken;
string? newRefreshToken = newToken.RefreshToken;
int expiresIn = newToken.ExpiresIn;Create providers with custom configurations at runtime:
// Create a custom provider configuration
var config = new ProviderConfig
{
ClientId = "dynamic-client-id",
ClientSecret = "dynamic-client-secret",
RedirectUrl = "https://your-app.com/auth/callback",
Stateless = true,
UsesPkce = true
};
// Add some scopes
config.Scopes.Add("email");
config.Scopes.Add("profile");
// Build the provider
IProvider provider = _socialite.BuildProvider("google", config);
// Use the provider as normal
string redirectUrl = await provider.RedirectAsync(HttpContext);Currently, SocialiteNET supports:
-
Google
- Default scopes:
openid,profile,email - Documentation: Google OAuth 2.0
- Default scopes:
-
GitHub
- Default scopes:
openid,profile,email - Documentation: GitHub OAuth Apps
- Default scopes:
We plan to add support for the following providers:
- Twitter/X
- Microsoft
- Slack
- Default scopes include
openid,profile, andemail - Map of user fields:
-
Id←sub -
Name←name -
Email←email -
Avatar←picture
-
You can create custom OAuth providers by extending the AbstractProvider class:
public class CustomProvider : AbstractProvider
{
public CustomProvider(
HttpClient httpClient,
string clientId,
string clientSecret,
string redirectUrl)
: base(httpClient, clientId, clientSecret, redirectUrl)
{
// Set provider-specific defaults
ScopeSeparator = " ";
Scopes.AddRange(["profile", "email"]);
}
protected override string GetAuthUrl(string? state)
{
return BuildAuthUrlFromBase("https://custom-provider.com/oauth/authorize", state);
}
protected override string GetTokenUrl()
{
return "https://custom-provider.com/oauth/token";
}
protected override async Task<Dictionary<string, object?>> GetUserByToken(string token)
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://custom-provider.com/api/user");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await HttpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
return JsonDocument.Parse(content).RootElement.DeserializeToDict();
}
protected override IUser MapUserToObject(Dictionary<string, object?> user)
{
return new User()
.SetRaw(user)
.Map(new Dictionary<string, object?>
{
["Id"] = user.TryGetValue("id", out var id) ? id?.ToString() : string.Empty,
["Name"] = user.TryGetValue("name", out var name) ? name?.ToString() : null,
["Email"] = user.TryGetValue("email", out var email) ? email?.ToString() : null,
["Avatar"] = user.TryGetValue("avatar_url", out var avatar) ? avatar?.ToString() : null
});
}
}Register your custom provider with Socialite:
// Register the provider with dependency injection
builder.Services.AddHttpClient<CustomProvider>();
builder.Services.AddTransient<CustomProvider>();
// Register with Socialite
builder.Services.AddSocialite()
.Extend("custom", serviceProvider =>
{
var httpClient = serviceProvider.GetRequiredService<HttpClient>();
return new CustomProvider(
httpClient,
configuration["Authentication:Custom:ClientId"],
configuration["Authentication:Custom:ClientSecret"],
configuration["Authentication:Custom:RedirectUrl"]
);
});
// Use your custom provider
var redirectUrl = await _socialite.GetProvider("custom")