diff --git a/DorkNet.Server/Services/ExternalSignIn.cs b/DorkNet.Server/Services/ExternalSignIn.cs index e2657b2..dda5ea5 100644 --- a/DorkNet.Server/Services/ExternalSignIn.cs +++ b/DorkNet.Server/Services/ExternalSignIn.cs @@ -26,6 +26,12 @@ public sealed class ExternalSignInOptions public string Scopes { get; set; } = "openid email profile"; + /// Also read the provider's userinfo endpoint after sign-in. Off by + /// default: the ID token already carries sub and email, and + /// Cloudflare Access answers userinfo without a Content-Type, which the + /// OpenID Connect handler rejects. + public bool UseUserInfoEndpoint { get; set; } + public bool IsConfigured => Authority.Length > 0 && ClientId.Length > 0 && ClientSecret.Length > 0; } diff --git a/DorkNet.Server/Startup/ServiceCollectionExtensions.cs b/DorkNet.Server/Startup/ServiceCollectionExtensions.cs index 41e8405..38f3caa 100644 --- a/DorkNet.Server/Startup/ServiceCollectionExtensions.cs +++ b/DorkNet.Server/Startup/ServiceCollectionExtensions.cs @@ -484,7 +484,7 @@ public static class ServiceCollectionExtensions o.Scope.Add(scope); o.SignInScheme = ExternalSignIn.ExternalScheme; o.CallbackPath = ExternalSignIn.CallbackPath; - o.GetClaimsFromUserInfoEndpoint = true; + o.GetClaimsFromUserInfoEndpoint = signIn.UseUserInfoEndpoint; o.MapInboundClaims = false; o.SaveTokens = false; o.CorrelationCookie.SecurePolicy = secure; diff --git a/docs/deploy.md b/docs/deploy.md index b025ccb..399f6e1 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -477,6 +477,9 @@ DorkNet__SignIn__ClientSecret= DorkNet__SignIn__DisplayName=Cloudflare # Optional: scopes, default "openid email profile". DorkNet__SignIn__Scopes=openid email profile +# Optional: also read the userinfo endpoint (default false; the ID token is +# enough for most providers, and Cloudflare Access's userinfo can't be read). +DorkNet__SignIn__UseUserInfoEndpoint=false ``` Register these redirect URIs at the provider, one per host people sign in on: