基于Electron.NET的Angular客户端IdentityServer4重定向URI配置问题
Hey there! Let's work through this problem since your Electron.NET Angular app is moving from a fixed local setup to devices with unknown public IPs—making that hardcoded http://localhost:4200/signin-oidc redirect URI in IdentityServer4 (IS4) obsolete. Here are the most practical, secure solutions tailored to desktop apps like yours:
Desktop apps rely on loopback (local) redirects because the authentication response is sent back to the user's local machine, not a public IP. This works regardless of the device's external IP.
Step 1: Configure IS4 to Allow Loopback URIs
Update your client configuration to include local loopback addresses, and optionally add a custom validator if you need to support random ports (to avoid conflicts):
new Client { ClientId = "electron-angular-client", ClientName = "Electron Angular Desktop App", AllowedGrantTypes = GrantTypes.Code, // Use Authorization Code Flow with PKCE (critical for public clients) RequirePkce = true, RequireClientSecret = false, // Desktop apps can't safely store secrets RedirectUris = new List<string> { "http://localhost:4200/signin-oidc", "http://127.0.0.1:4200/signin-oidc" }, PostLogoutRedirectUris = new List<string> { "http://localhost:4200/signout-callback-oidc", "http://127.0.0.1:4200/signout-callback-oidc" }, AllowedScopes = { "openid", "profile", "your-api-scopes" } }
Optional: Support Random Local Ports
If your Electron app might use random ports (to avoid port collisions), create a custom redirect URI validator to allow any localhost-based URI:
public class LoopbackUriValidator : IRedirectUriValidator { public Task<bool> IsRedirectUriValidAsync(string requestedUri, Client client) { var isLoopback = requestedUri.StartsWith("http://localhost:") || requestedUri.StartsWith("http://127.0.0.1:"); return Task.FromResult(isLoopback || client.RedirectUris.Contains(requestedUri)); } public Task<bool> IsPostLogoutRedirectUriValidAsync(string requestedUri, Client client) { var isLoopback = requestedUri.StartsWith("http://localhost:") || requestedUri.StartsWith("http://127.0.0.1:"); return Task.FromResult(isLoopback || client.PostLogoutRedirectUris.Contains(requestedUri)); } }
Register it in your IS4 Startup:
services.AddIdentityServer() // Other config (stores, resources, etc.) .AddRedirectUriValidator<LoopbackUriValidator>();
Step 2: Update Your Angular OIDC Config
Dynamically set the redirect URI based on your app's current origin (so it adapts to whatever port Electron uses):
import { AuthConfig } from 'angular-oauth2-oidc'; export const authConfig: AuthConfig = { issuer: 'https://your-production-is4-url', clientId: 'electron-angular-client', redirectUri: window.location.origin + '/signin-oidc', postLogoutRedirectUri: window.location.origin + '/signout-callback-oidc', responseType: 'code', scope: 'openid profile your-api-scopes', useSilentRefresh: true, requireHttps: true // Enforce this in production! };
For a smoother desktop experience, register a custom protocol (like myapp://) so IS4 redirects directly to your app instead of a local web server.
Step 1: Configure IS4 for Custom Protocol
Update your client config to use the custom URI:
new Client { ClientId = "electron-angular-client", AllowedGrantTypes = GrantTypes.Code, RequirePkce = true, RequireClientSecret = false, RedirectUris = { "myapp://signin-oidc" }, PostLogoutRedirectUris = { "myapp://signout-callback-oidc" }, AllowedScopes = { "openid", "profile", "your-api-scopes" } }
Step 2: Register the Protocol in Electron.NET
Add this to your Electron startup code (e.g., Program.cs) to register the custom protocol with the OS:
await Electron.App.SetAsDefaultProtocolClientAsync("myapp");
Step 3: Update Angular OIDC Config
Set the redirect URI to your custom protocol:
export const authConfig: AuthConfig = { // Other config... redirectUri: 'myapp://signin-oidc', postLogoutRedirectUri: 'myapp://signout-callback-oidc', };
You'll also need to handle the protocol activation event in Electron to capture the authentication response and pass it to your Angular app.
If you need to support completely unknown client environments, enable IS4's dynamic client registration feature. This lets your app register itself with IS4 on first launch, including its redirect URI.
Step 1: Enable Dynamic Registration in IS4
Add this to your IS4 Startup:
services.AddIdentityServer() // Other config... .AddDynamicClientRegistration();
You can restrict registration to trusted parties using client assertions or API keys to avoid abuse.
Step 2: Register the Client from Your Electron App
On first launch, send a POST request to IS4's connect/register endpoint with your app's details (including redirect URI). IS4 will return a client ID and other config, which you can store locally for future authentication requests.
Critical Notes for All Solutions
- Always use PKCE: Desktop apps are "public clients" (can't safely store secrets), so PKCE is mandatory to prevent authorization code hijacking.
- Avoid Implicit Flow: The Authorization Code Flow (with PKCE) is the OIDC-recommended flow for public clients.
- Enforce HTTPS: In production, ensure your IS4 instance uses HTTPS to secure authentication traffic.
内容的提问来源于stack exchange,提问作者Thomas D.

