mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: Allow multiple OIDC domains (#5210)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
This commit is contained in:
co-authored by
Mathias Fredriksson
parent
02bb052d09
commit
061635c36d
@@ -216,9 +216,9 @@ func newConfig() *codersdk.DeploymentConfig {
|
||||
Flag: "oidc-client-secret",
|
||||
Secret: true,
|
||||
},
|
||||
EmailDomain: &codersdk.DeploymentConfigField[string]{
|
||||
EmailDomain: &codersdk.DeploymentConfigField[[]string]{
|
||||
Name: "OIDC Email Domain",
|
||||
Usage: "Email domain that clients logging in with OIDC must match.",
|
||||
Usage: "Email domains that clients logging in with OIDC must match.",
|
||||
Flag: "oidc-email-domain",
|
||||
},
|
||||
IssuerURL: &codersdk.DeploymentConfigField[string]{
|
||||
|
||||
@@ -154,7 +154,7 @@ func TestConfig(t *testing.T) {
|
||||
},
|
||||
Valid: func(config *codersdk.DeploymentConfig) {
|
||||
require.Equal(t, config.OIDC.IssuerURL.Value, "https://accounts.google.com")
|
||||
require.Equal(t, config.OIDC.EmailDomain.Value, "coder.com")
|
||||
require.Equal(t, config.OIDC.EmailDomain.Value, []string{"coder.com"})
|
||||
require.Equal(t, config.OIDC.ClientID.Value, "client")
|
||||
require.Equal(t, config.OIDC.ClientSecret.Value, "secret")
|
||||
require.False(t, config.OIDC.AllowSignups.Value)
|
||||
|
||||
+2
-2
@@ -95,8 +95,8 @@ Flags:
|
||||
Consumes $CODER_OIDC_CLIENT_ID
|
||||
--oidc-client-secret string Client secret to use for Login with OIDC.
|
||||
Consumes $CODER_OIDC_CLIENT_SECRET
|
||||
--oidc-email-domain string Email domain that clients logging in with
|
||||
OIDC must match.
|
||||
--oidc-email-domain strings Email domains that clients logging in
|
||||
with OIDC must match.
|
||||
Consumes $CODER_OIDC_EMAIL_DOMAIN
|
||||
--oidc-ignore-email-verified Ignore the email_verified claim from the
|
||||
upstream provider.
|
||||
|
||||
+12
-5
@@ -192,8 +192,8 @@ type OIDCConfig struct {
|
||||
httpmw.OAuth2Config
|
||||
|
||||
Verifier *oidc.IDTokenVerifier
|
||||
// EmailDomain is the domain to enforce when a user authenticates.
|
||||
EmailDomain string
|
||||
// EmailDomains are the domains to enforce when a user authenticates.
|
||||
EmailDomain []string
|
||||
AllowSignups bool
|
||||
// IgnoreEmailVerified allows ignoring the email_verified claim
|
||||
// from an upstream OIDC provider. See #5065 for context.
|
||||
@@ -289,10 +289,17 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
username = httpapi.UsernameFrom(username)
|
||||
}
|
||||
if api.OIDCConfig.EmailDomain != "" {
|
||||
if !strings.HasSuffix(strings.ToLower(email), strings.ToLower(api.OIDCConfig.EmailDomain)) {
|
||||
if len(api.OIDCConfig.EmailDomain) > 0 {
|
||||
ok = false
|
||||
for _, domain := range api.OIDCConfig.EmailDomain {
|
||||
if strings.HasSuffix(strings.ToLower(email), strings.ToLower(domain)) {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{
|
||||
Message: fmt.Sprintf("Your email %q is not a part of the %q domain!", email, api.OIDCConfig.EmailDomain),
|
||||
Message: fmt.Sprintf("Your email %q is not in domains %q !", email, api.OIDCConfig.EmailDomain),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ func TestUserOIDC(t *testing.T) {
|
||||
Name string
|
||||
Claims jwt.MapClaims
|
||||
AllowSignups bool
|
||||
EmailDomain string
|
||||
EmailDomain []string
|
||||
Username string
|
||||
AvatarURL string
|
||||
StatusCode int
|
||||
@@ -528,8 +528,10 @@ func TestUserOIDC(t *testing.T) {
|
||||
"email_verified": true,
|
||||
},
|
||||
AllowSignups: true,
|
||||
EmailDomain: "coder.com",
|
||||
StatusCode: http.StatusForbidden,
|
||||
EmailDomain: []string{
|
||||
"coder.com",
|
||||
},
|
||||
StatusCode: http.StatusForbidden,
|
||||
}, {
|
||||
Name: "EmailDomainCaseInsensitive",
|
||||
Claims: jwt.MapClaims{
|
||||
@@ -537,8 +539,10 @@ func TestUserOIDC(t *testing.T) {
|
||||
"email_verified": true,
|
||||
},
|
||||
AllowSignups: true,
|
||||
EmailDomain: "kwc.io",
|
||||
StatusCode: http.StatusTemporaryRedirect,
|
||||
EmailDomain: []string{
|
||||
"kwc.io",
|
||||
},
|
||||
StatusCode: http.StatusTemporaryRedirect,
|
||||
}, {
|
||||
Name: "EmptyClaims",
|
||||
Claims: jwt.MapClaims{},
|
||||
|
||||
@@ -91,7 +91,7 @@ type OIDCConfig struct {
|
||||
AllowSignups *DeploymentConfigField[bool] `json:"allow_signups" typescript:",notnull"`
|
||||
ClientID *DeploymentConfigField[string] `json:"client_id" typescript:",notnull"`
|
||||
ClientSecret *DeploymentConfigField[string] `json:"client_secret" typescript:",notnull"`
|
||||
EmailDomain *DeploymentConfigField[string] `json:"email_domain" typescript:",notnull"`
|
||||
EmailDomain *DeploymentConfigField[[]string] `json:"email_domain" typescript:",notnull"`
|
||||
IssuerURL *DeploymentConfigField[string] `json:"issuer_url" typescript:",notnull"`
|
||||
Scopes *DeploymentConfigField[[]string] `json:"scopes" typescript:",notnull"`
|
||||
IgnoreEmailVerified *DeploymentConfigField[bool] `json:"ignore_email_verified" typescript:",notnull"`
|
||||
|
||||
+2
-2
@@ -63,7 +63,7 @@ Navigate to your Coder host and run the following command to start up the Coder
|
||||
server:
|
||||
|
||||
```console
|
||||
coder server --oidc-issuer-url="https://accounts.google.com" --oidc-email-domain="your-domain" --oidc-client-id="533...ent.com" --oidc-client-secret="G0CSP...7qSM"
|
||||
coder server --oidc-issuer-url="https://accounts.google.com" --oidc-email-domain="your-domain-1,your-domain-2" --oidc-client-id="533...ent.com" --oidc-client-secret="G0CSP...7qSM"
|
||||
```
|
||||
|
||||
Alternatively, if you are running Coder as a system service, you can achieve the
|
||||
@@ -72,7 +72,7 @@ to the `/etc/coder.d/coder.env` file:
|
||||
|
||||
```console
|
||||
CODER_OIDC_ISSUER_URL="https://accounts.google.com"
|
||||
CODER_OIDC_EMAIL_DOMAIN="your-domain"
|
||||
CODER_OIDC_EMAIL_DOMAIN="your-domain-1,your-domain-2"
|
||||
CODER_OIDC_CLIENT_ID="533...ent.com"
|
||||
CODER_OIDC_CLIENT_SECRET="G0CSP...7qSM"
|
||||
```
|
||||
|
||||
@@ -442,7 +442,7 @@ export interface OIDCConfig {
|
||||
readonly allow_signups: DeploymentConfigField<boolean>
|
||||
readonly client_id: DeploymentConfigField<string>
|
||||
readonly client_secret: DeploymentConfigField<string>
|
||||
readonly email_domain: DeploymentConfigField<string>
|
||||
readonly email_domain: DeploymentConfigField<string[]>
|
||||
readonly issuer_url: DeploymentConfigField<string>
|
||||
readonly scopes: DeploymentConfigField<string[]>
|
||||
readonly ignore_email_verified: DeploymentConfigField<boolean>
|
||||
|
||||
Reference in New Issue
Block a user