зеркало из https://github.com/mozilla/doorman.git
First phase, using payload info (ref #55)
This commit is contained in:
Родитель
214303141d
Коммит
23e34032f6
|
@ -2,6 +2,7 @@ package doorman
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
jwt "gopkg.in/square/go-jose.v2/jwt"
|
||||
)
|
||||
|
@ -31,14 +32,22 @@ func NewJWTValidator(issuer string) (JWTValidator, error) {
|
|||
// Reuse JWT validators instances among configs if they are for the same issuer.
|
||||
v, ok := jwtValidators[issuer]
|
||||
if !ok {
|
||||
// XXX: currently only Auth0 is supported.
|
||||
v = &Auth0Validator{
|
||||
Issuer: issuer,
|
||||
if strings.Contains(issuer, "mozilla.auth0.com") {
|
||||
v = &MozillaAuth0Validator{
|
||||
Issuer: issuer,
|
||||
}
|
||||
} else {
|
||||
// Fallback on basic Auth0.
|
||||
// XXX: Here is where we can add other Identity providers.
|
||||
v = &Auth0Validator{
|
||||
Issuer: issuer,
|
||||
}
|
||||
}
|
||||
err := v.Initialize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jwtValidators[issuer] = v
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
|
|
@ -18,18 +18,11 @@ type Auth0Validator struct {
|
|||
|
||||
// Initialize will fetch Auth0 public keys and instantiate a validator.
|
||||
func (v *Auth0Validator) Initialize() error {
|
||||
if !strings.HasPrefix(v.Issuer, "https://") || !strings.HasSuffix(v.Issuer, "auth0.com/") {
|
||||
return fmt.Errorf("issuer %q not supported or has bad format", v.Issuer)
|
||||
validator, err := auth0Validator(v.Issuer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jwksURI := fmt.Sprintf("%s.well-known/jwks.json", v.Issuer)
|
||||
log.Infof("JWT keys: %s", jwksURI)
|
||||
|
||||
// Will check audience only when request comes in, leave empty for now.
|
||||
audience := []string{}
|
||||
|
||||
client := auth0.NewJWKClient(auth0.JWKClientOptions{URI: jwksURI})
|
||||
config := auth0.NewConfiguration(client, audience, v.Issuer, jose.RS256)
|
||||
v.validator = auth0.NewValidator(config)
|
||||
v.validator = validator
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -43,3 +36,16 @@ func (v *Auth0Validator) ExtractClaims(request *http.Request) (*Claims, error) {
|
|||
}
|
||||
return &claims, nil
|
||||
}
|
||||
|
||||
func auth0Validator(issuer string) (*auth0.JWTValidator, error) {
|
||||
if !strings.HasPrefix(issuer, "https://") || !strings.HasSuffix(issuer, "auth0.com/") {
|
||||
return nil, fmt.Errorf("issuer %q not supported or has bad format", issuer)
|
||||
}
|
||||
jwksURI := fmt.Sprintf("%s.well-known/jwks.json", issuer)
|
||||
log.Infof("JWT keys: %s", jwksURI)
|
||||
// Will check audience only when request comes in, leave empty for now.
|
||||
audience := []string{}
|
||||
client := auth0.NewJWKClient(auth0.JWKClientOptions{URI: jwksURI})
|
||||
config := auth0.NewConfiguration(client, audience, issuer, jose.RS256)
|
||||
return auth0.NewValidator(config), nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package doorman
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
auth0 "github.com/auth0-community/go-auth0"
|
||||
jwt "gopkg.in/square/go-jose.v2/jwt"
|
||||
)
|
||||
|
||||
// MozillaClaims uses specific attributes for emails and groups
|
||||
type MozillaClaims struct {
|
||||
Subject string `json:"sub,omitempty"`
|
||||
Audience jwt.Audience `json:"aud,omitempty"`
|
||||
Emails []string `json:"https://sso.mozilla.com/claim/emails,omitempty"`
|
||||
Groups []string `json:"https://sso.mozilla.com/claim/groups,omitempty"`
|
||||
}
|
||||
|
||||
// MozillaAuth0Validator is the implementation of JWTValidator for Auth0.
|
||||
type MozillaAuth0Validator struct {
|
||||
Issuer string
|
||||
validator *auth0.JWTValidator
|
||||
}
|
||||
|
||||
// Initialize will fetch Auth0 public keys and instantiate a validator.
|
||||
func (v *MozillaAuth0Validator) Initialize() error {
|
||||
validator, err := auth0Validator(v.Issuer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.validator = validator
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExtractClaims validates the token from request, and returns the JWT claims.
|
||||
func (v *MozillaAuth0Validator) ExtractClaims(request *http.Request) (*Claims, error) {
|
||||
token, err := v.validator.ValidateRequest(request)
|
||||
mozclaims := MozillaClaims{}
|
||||
err = v.validator.Claims(request, token, &mozclaims)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
claims := Claims{
|
||||
Subject: mozclaims.Subject,
|
||||
Audience: mozclaims.Audience,
|
||||
Email: mozclaims.Emails[0],
|
||||
Groups: mozclaims.Groups,
|
||||
}
|
||||
return &claims, nil
|
||||
}
|
Загрузка…
Ссылка в новой задаче