Skip to content

Commit

Permalink
feat(security): added the ability to use a different claim field to m…
Browse files Browse the repository at this point in the history
…atch 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'.
  • Loading branch information
fulvius committed May 14, 2024
1 parent 9d151fc commit e5b6b17
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,7 @@ security:
| `security.oidc.client-secret` | Client secret | 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.claim-to-check` | Name of the field to use to match against `allowed-subjects` | `""` |

```yaml
security:
Expand All @@ -1529,6 +1530,8 @@ security:
scopes: ["openid"]
# You may optionally specify a list of allowed subjects. If this is not specified, all subjects will be allowed.
#allowed-subjects: ["[email protected]"]
# 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).
Expand Down
34 changes: 28 additions & 6 deletions security/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type OIDCConfig struct {
ClientSecret string `yaml:"client-secret"`
Scopes []string `yaml:"scopes"` // e.g. ["openid"]
AllowedSubjects []string `yaml:"allowed-subjects"` // e.g. ["[email protected]"]. If empty, all subjects are allowed
ClaimToCheck string `yaml:"claim-to-check"` // e.g. email. If empty, subject is used

oauth2Config oauth2.Config
verifier *oidc.IDTokenVerifier
Expand Down Expand Up @@ -117,14 +118,35 @@ func (c *OIDCConfig) callbackHandler(w http.ResponseWriter, r *http.Request) { /
http.Redirect(w, r, "/", http.StatusFound)
return
}
for _, subject := range c.AllowedSubjects {
if strings.ToLower(subject) == strings.ToLower(idToken.Subject) {
c.setSessionCookie(w, idToken)
http.Redirect(w, r, "/", http.StatusFound)
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 {
if strings.ToLower(subject) == strings.ToLower(idToken.Subject) {
c.setSessionCookie(w, idToken)
http.Redirect(w, r, "/", http.StatusFound)
return
}
}
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)
}

Expand Down

0 comments on commit e5b6b17

Please sign in to comment.