External Authentication Providers Setup
This guide explains how to configure external identity providers (Google, GitHub, Microsoft, Apple) for social login in Wallow.
Overview
Wallow supports sign-in via external identity providers alongside traditional email/password authentication. When configured, social login buttons appear on the Login and Register pages. Providers that are not configured are automatically hidden from the UI.
External authentication works alongside OpenIddict -- the external provider authenticates the user, then Wallow links (or creates) a local account and issues its own OpenIddict tokens with tenant context.
How It Works
User clicks "Sign in with Google"
|
v
GET /v1/identity/auth/external-login?provider=Google&returnUrl=...
|
v
Browser redirects to provider (e.g. accounts.google.com)
|
v
User authenticates with provider
|
v
Provider redirects back to callback:
GET /v1/identity/auth/external-login-callback?returnUrl=...
|
+-- Existing linked account --> Sign in immediately
|
+-- Email matches verified account --> Auto-link provider, sign in
|
+-- New user --> Redirect to /accept-terms --> Create account
Note
The API serves these routes at /v1/…; no controller in the codebase carries an /api prefix.
/api does exist in Wallow, but as a mount, not as part of the API's own paths: the
wallow-web BFF proxies its same-origin /api/** to the API, and an ingress doing path-based
routing can mount the API under /api via the opt-in PathBase. Which prefix you use depends on
which door you knock on — a browser going through the BFF calls /api/v1/…, while anything
talking to the API directly calls /v1/….
Provider Setup
Each provider requires creating an OAuth/OIDC application in that provider's developer console and obtaining credentials. Only providers with valid credentials will appear as login options.
- Go to Google Cloud Console > Credentials
- Create a new project (or select existing)
- Click Create Credentials > OAuth client ID
- Application type: Web application
- Add authorized redirect URI:
https://<your-domain>/signin-google- For local development:
http://localhost:5001/signin-google
- For local development:
- Copy the Client ID and Client Secret
Configuration:
{
"Authentication": {
"Google": {
"ClientId": "your-client-id.apps.googleusercontent.com",
"ClientSecret": "GOCSPX-your-client-secret"
}
}
}
GitHub
- Go to GitHub > Settings > Developer settings > OAuth Apps
- Click New OAuth App
- Set Authorization callback URL:
https://<your-domain>/signin-github- For local development:
http://localhost:5001/signin-github
- For local development:
- Copy the Client ID and generate a Client Secret
Configuration:
{
"Authentication": {
"GitHub": {
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret"
}
}
}
Microsoft (Azure AD / Entra ID)
- Go to Azure Portal > App registrations
- Click New registration
- Supported account types: choose based on your needs (personal, work, or both)
- Add redirect URI (Web):
https://<your-domain>/signin-microsoft- For local development:
http://localhost:5001/signin-microsoft
- For local development:
- Go to Certificates & secrets > New client secret
- Copy the Application (client) ID and the secret value
Configuration:
{
"Authentication": {
"Microsoft": {
"ClientId": "your-application-id",
"ClientSecret": "your-client-secret"
}
}
}
Apple
Apple Sign In requires an Apple Developer Program membership ($99/year).
- Go to Apple Developer > Certificates, Identifiers & Profiles
- Register an App ID with "Sign In with Apple" capability
- Register a Services ID (this is your
ServiceId/ClientId)- Add your domain and return URL:
https://<your-domain>/signin-apple
- Add your domain and return URL:
- Create a Key with "Sign In with Apple" enabled
- Download the
.p8key file (you only get one download) - Note the Key ID
- Download the
- Your Team ID is shown in the top-right of the developer portal
Configuration:
{
"Authentication": {
"Apple": {
"ServiceId": "com.yourcompany.yourapp",
"TeamId": "YOUR_TEAM_ID",
"KeyId": "YOUR_KEY_ID"
}
}
}
Note: The Apple
.p8private key file must be accessible to the application at runtime for client secret generation. See the AspNet.Security.OAuth.Apple documentation for key file configuration options.
Configuration Methods
User Secrets (Local Development)
dotnet user-secrets set "Authentication:Google:ClientId" "your-client-id" --project api/src/Wallow.Api
dotnet user-secrets set "Authentication:Google:ClientSecret" "your-secret" --project api/src/Wallow.Api
Environment Variables (Production)
export Authentication__Google__ClientId="your-client-id"
export Authentication__Google__ClientSecret="your-secret"
appsettings.json (Development Only)
Add to api/src/Wallow.Api/appsettings.Development.json. Never commit secrets to source control.
How Provider Visibility Works
The backend conditionally registers authentication schemes only when credentials are present (see IdentityInfrastructureExtensions.cs). The API exposes a GET /v1/identity/auth/external-providers endpoint that returns the list of configured providers. The Login and Register pages query this endpoint and only render buttons for enabled providers.
If no external providers are configured, the "Or continue with" separator and all social buttons are hidden entirely.
Configuration Reference
| Provider | Required Keys | Optional |
|---|---|---|
ClientId, ClientSecret |
-- | |
| GitHub | ClientId, ClientSecret |
-- |
| Microsoft | ClientId, ClientSecret |
-- |
| Apple | ServiceId, TeamId, KeyId |
-- |
Redirect URIs
Each provider requires a redirect URI registered in its developer console. The format is:
https://<your-api-domain>/signin-<provider>
| Provider | Redirect URI Path |
|---|---|
/signin-google |
|
| GitHub | /signin-github |
| Microsoft | /signin-microsoft |
| Apple | /signin-apple |
For local development, the API typically runs on http://localhost:5001. Some providers (notably Apple) require HTTPS even for development.
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| Button not showing | Provider credentials missing or empty | Verify config values are set and non-empty |
| "external_login_failed" error | Redirect URI mismatch | Ensure the redirect URI in the provider console exactly matches your API URL |
| "external_login_failed" error | Client secret expired/rotated | Regenerate and update the secret |
| Apple sign-in fails | .p8 key not accessible |
Ensure key file path is correct and readable |
| No email claim returned | Provider privacy settings | Some providers allow users to hide email; GitHub requires user:email scope (already configured) |