| 168 | } |
| 169 | |
| 170 | func createOIDCConfig(ctx context.Context, logger slog.Logger, vals *codersdk.DeploymentValues) (*coderd.OIDCConfig, error) { |
| 171 | if vals.OIDC.ClientID == "" { |
| 172 | return nil, xerrors.Errorf("OIDC client ID must be set!") |
| 173 | } |
| 174 | if vals.OIDC.IssuerURL == "" { |
| 175 | return nil, xerrors.Errorf("OIDC issuer URL must be set!") |
| 176 | } |
| 177 | |
| 178 | // Skipping issuer checks is not recommended. |
| 179 | if vals.OIDC.SkipIssuerChecks { |
| 180 | logger.Warn(ctx, "issuer checks with OIDC is disabled. This is not recommended as it can compromise the security of the authentication") |
| 181 | ctx = oidc.InsecureIssuerURLContext(ctx, vals.OIDC.IssuerURL.String()) |
| 182 | } |
| 183 | |
| 184 | oidcProvider, err := oidc.NewProvider( |
| 185 | ctx, vals.OIDC.IssuerURL.String(), |
| 186 | ) |
| 187 | if err != nil { |
| 188 | return nil, xerrors.Errorf("configure oidc provider: %w", err) |
| 189 | } |
| 190 | redirectURL, err := vals.AccessURL.Value().Parse("/api/v2/users/oidc/callback") |
| 191 | if err != nil { |
| 192 | return nil, xerrors.Errorf("parse oidc oauth callback url: %w", err) |
| 193 | } |
| 194 | |
| 195 | if vals.OIDC.RedirectURL.String() != "" { |
| 196 | redirectURL, err = vals.OIDC.RedirectURL.Value().Parse("/api/v2/users/oidc/callback") |
| 197 | if err != nil { |
| 198 | return nil, xerrors.Errorf("parse oidc redirect url %q", err) |
| 199 | } |
| 200 | logger.Warn(ctx, "custom OIDC redirect URL used instead of 'access_url', ensure this matches the value configured in your OIDC provider") |
| 201 | } |
| 202 | |
| 203 | // If the scopes contain 'groups', we enable group support. |
| 204 | // Do not override any custom value set by the user. |
| 205 | if slice.Contains(vals.OIDC.Scopes, "groups") && vals.OIDC.GroupField == "" { |
| 206 | vals.OIDC.GroupField = "groups" |
| 207 | } |
| 208 | oauthCfg := &oauth2.Config{ |
| 209 | ClientID: vals.OIDC.ClientID.String(), |
| 210 | ClientSecret: vals.OIDC.ClientSecret.String(), |
| 211 | RedirectURL: redirectURL.String(), |
| 212 | Endpoint: oidcProvider.Endpoint(), |
| 213 | Scopes: vals.OIDC.Scopes, |
| 214 | } |
| 215 | |
| 216 | var useCfg promoauth.OAuth2Config = oauthCfg |
| 217 | if vals.OIDC.ClientKeyFile != "" { |
| 218 | // PKI authentication is done in the params. If a |
| 219 | // counter example is found, we can add a config option to |
| 220 | // change this. |
| 221 | oauthCfg.Endpoint.AuthStyle = oauth2.AuthStyleInParams |
| 222 | if vals.OIDC.ClientSecret != "" { |
| 223 | return nil, xerrors.Errorf("cannot specify both oidc client secret and oidc client key file") |
| 224 | } |
| 225 | |
| 226 | pkiCfg, err := configureOIDCPKI(oauthCfg, vals.OIDC.ClientKeyFile.Value(), vals.OIDC.ClientCertFile.Value()) |
| 227 | if err != nil { |