{"record":{"id":"fcdecd61c814ef8a","repo":"siyuan-note/siyuan","slug":"oidc-issuer-url-is-required-fcdecd","errorCode":null,"errorMessage":"OIDC issuer URL is required","messagePattern":"OIDC issuer URL is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/oidc_provider/provider.go","lineNumber":61,"sourceCode":"\t\treturn nil, errors.New(\"OIDC redirect URL is required\")\n\t}\n\tif config.Provider == conf.OIDCProviderGitHub && config.ClientSecret == \"\" {\n\t\treturn nil, errors.New(\"GitHub OAuth client secret is required\")\n\t}\n\tissuerURL := strings.TrimSpace(config.IssuerURL)\n\tswitch config.Provider {\n\tcase conf.OIDCProviderGoogle:\n\t\tissuerURL = googleIssuer\n\tcase conf.OIDCProviderMicrosoft:\n\t\t// Microsoft 多租户端点的 issuer 会随租户变化，必须使用租户专属 issuer。\n\tcase conf.OIDCProviderCustom:\n\tcase conf.OIDCProviderGitHub:\n\t\treturn newGitHub(config, redirectURL), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported OIDC provider [%s]\", config.Provider)\n\t}\n\tif issuerURL == \"\" {\n\t\treturn nil, errors.New(\"OIDC issuer URL is required\")\n\t}\n\tdiscovered, err := oidc.NewProvider(ctx, issuerURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"discover OIDC provider failed: %w\", err)\n\t}\n\tscopes := append([]string{}, config.Scopes...)\n\tif !contains(scopes, oidc.ScopeOpenID) {\n\t\tscopes = append([]string{oidc.ScopeOpenID}, scopes...)\n\t}\n\treturn &Provider{\n\t\tkind: conf.OIDCProviderCustom,\n\t\toauth2Config: &oauth2.Config{\n\t\t\tClientID:     config.ClientID,\n\t\t\tClientSecret: config.ClientSecret,\n\t\t\tEndpoint:     discovered.Endpoint(),\n\t\t\tRedirectURL:  redirectURL,\n\t\t\tScopes:       scopes,\n\t\t},","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/oidc_provider/provider.go#L43-L79","documentation":"Thrown by oidc_provider.New() when issuerURL is empty after the provider switch resolves. Google hard-codes its issuer, GitHub returns early before this check, but Microsoft and Custom rely on config.IssuerURL being populated. If the admin selected Custom or Microsoft but left the issuer URL blank, discovery cannot proceed.","triggerScenarios":"Calling New() with config.Provider == conf.OIDCProviderCustom or conf.OIDCProviderMicrosoft, and config.IssuerURL is empty or whitespace-only (TrimSpace yields empty). The switch falls through without setting issuerURL, and the subsequent empty check fires.","commonSituations":"The admin chose 'Custom' OIDC provider to connect a self-hosted Keycloak/Authelia/etc. but did not fill in the issuer URL (e.g., https://keycloak.example.com/realms/myrealm). The Microsoft provider was selected but the tenant-specific issuer URL was not provided.","solutions":["For Custom provider: enter the full issuer URL from your OIDC provider's well-known configuration (e.g., https://provider.example.com/.well-known/openid-configuration — use the base, not the .well-known path).","For Microsoft: provide the tenant-specific issuer URL since the multi-tenant endpoint issuer varies.","Validate IssuerURL is non-empty in the API handler when provider is Custom or Microsoft."],"exampleFix":"// before\nconfig.Provider = conf.OIDCProviderCustom\nconfig.IssuerURL = \"\"\n\n// after\nconfig.Provider = conf.OIDCProviderCustom\nconfig.IssuerURL = \"https://keycloak.example.com/realms/myrealm\"","handlingStrategy":"validation","validationCode":"if (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && strings.TrimSpace(config.IssuerURL) == \"\" {\n    return nil, errors.New(\"OIDC issuer URL is required for custom and Microsoft providers\")\n}\nprovider, err := oidc_provider.New(ctx, config, redirectURL)","typeGuard":"func hasIssuerURL(c *conf.OIDC) bool {\n    switch c.Provider {\n    case conf.OIDCProviderGoogle, conf.OIDCProviderGitHub:\n        return true // issuer is hardcoded or not needed\n    }\n    return strings.TrimSpace(c.IssuerURL) != \"\"\n}","tryCatchPattern":null,"preventionTips":["For Custom/Microsoft providers, always fill in the IssuerURL field.","Verify the issuer URL by appending /.well-known/openid-configuration and checking it returns JSON."],"tags":["oidc","authentication","config","issuer","validation"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}