mirror of
https://github.com/TwiN/gatus.git
synced 2025-08-20 11:33:27 +02:00
feat(security): added the ability to use a different claim field to match against the allow-subjects list.
In this way you can use 'email' or 'preferred_username' to identify the users. If not specified the default is 'subject'.
This commit is contained in:
@@ -1518,6 +1518,7 @@ security:
|
|||||||
| `security.oidc.client-secret` | Client secret | Required `""` |
|
| `security.oidc.client-secret` | Client secret | Required `""` |
|
||||||
| `security.oidc.scopes` | Scopes to request. The only scope you need is `openid`. | Required `[]` |
|
| `security.oidc.scopes` | Scopes to request. The only scope you need is `openid`. | Required `[]` |
|
||||||
| `security.oidc.allowed-subjects` | List of subjects to allow. If empty, all subjects are allowed. | `[]` |
|
| `security.oidc.allowed-subjects` | List of subjects to allow. If empty, all subjects are allowed. | `[]` |
|
||||||
|
| `security.oidc.claim-to-check` | Name of the field to use to match against `allowed-subjects` | `""` |
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
security:
|
security:
|
||||||
@@ -1529,6 +1530,8 @@ security:
|
|||||||
scopes: ["openid"]
|
scopes: ["openid"]
|
||||||
# You may optionally specify a list of allowed subjects. If this is not specified, all subjects will be allowed.
|
# You may optionally specify a list of allowed subjects. If this is not specified, all subjects will be allowed.
|
||||||
#allowed-subjects: ["johndoe@example.com"]
|
#allowed-subjects: ["johndoe@example.com"]
|
||||||
|
# You can specify a different claim field to match against allowed-subjects. If not specified "subject" is used.
|
||||||
|
#claim-to-check: "preferred_username"
|
||||||
```
|
```
|
||||||
|
|
||||||
Confused? Read [Securing Gatus with OIDC using Auth0](https://twin.sh/articles/56/securing-gatus-with-oidc-using-auth0).
|
Confused? Read [Securing Gatus with OIDC using Auth0](https://twin.sh/articles/56/securing-gatus-with-oidc-using-auth0).
|
||||||
|
@@ -21,6 +21,7 @@ type OIDCConfig struct {
|
|||||||
ClientSecret string `yaml:"client-secret"`
|
ClientSecret string `yaml:"client-secret"`
|
||||||
Scopes []string `yaml:"scopes"` // e.g. ["openid"]
|
Scopes []string `yaml:"scopes"` // e.g. ["openid"]
|
||||||
AllowedSubjects []string `yaml:"allowed-subjects"` // e.g. ["user1@example.com"]. If empty, all subjects are allowed
|
AllowedSubjects []string `yaml:"allowed-subjects"` // e.g. ["user1@example.com"]. If empty, all subjects are allowed
|
||||||
|
ClaimToCheck string `yaml:"claim-to-check"` // e.g. email. If empty, subject is used
|
||||||
|
|
||||||
oauth2Config oauth2.Config
|
oauth2Config oauth2.Config
|
||||||
verifier *oidc.IDTokenVerifier
|
verifier *oidc.IDTokenVerifier
|
||||||
@@ -117,6 +118,26 @@ func (c *OIDCConfig) callbackHandler(w http.ResponseWriter, r *http.Request) { /
|
|||||||
http.Redirect(w, r, "/", http.StatusFound)
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var claimToCheck = c.ClaimToCheck
|
||||||
|
if len(claimToCheck) > 0 {
|
||||||
|
var claimsMap map[string]interface{}
|
||||||
|
if err := idToken.Claims(&claimsMap); err == nil {
|
||||||
|
claimValue, ok := claimsMap[claimToCheck]
|
||||||
|
if ok {
|
||||||
|
for _, subject := range c.AllowedSubjects {
|
||||||
|
if claimValue == subject {
|
||||||
|
c.setSessionCookie(w, idToken)
|
||||||
|
http.Redirect(w, r, "/", http.StatusFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("[security.callbackHandler] Value %s of claim %s doesn't match any element of the list of allowed subjects", claimValue, claimToCheck)
|
||||||
|
} else {
|
||||||
|
log.Printf("[security.callbackHandler] Claim doesn't contain the field %s", claimToCheck)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for _, subject := range c.AllowedSubjects {
|
for _, subject := range c.AllowedSubjects {
|
||||||
if strings.ToLower(subject) == strings.ToLower(idToken.Subject) {
|
if strings.ToLower(subject) == strings.ToLower(idToken.Subject) {
|
||||||
c.setSessionCookie(w, idToken)
|
c.setSessionCookie(w, idToken)
|
||||||
@@ -125,6 +146,7 @@ func (c *OIDCConfig) callbackHandler(w http.ResponseWriter, r *http.Request) { /
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Printf("[security.callbackHandler] Subject %s is not in the list of allowed subjects", idToken.Subject)
|
log.Printf("[security.callbackHandler] Subject %s is not in the list of allowed subjects", idToken.Subject)
|
||||||
|
}
|
||||||
http.Redirect(w, r, "/?error=access_denied", http.StatusFound)
|
http.Redirect(w, r, "/?error=access_denied", http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user