First phase, using payload info (ref #55)

This commit is contained in:
Mathieu Leplatre 2017-12-04 18:12:04 +01:00
Родитель 214303141d
Коммит 23e34032f6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 767B105F81A15CDD
3 изменённых файлов: 78 добавлений и 14 удалений

Просмотреть файл

@ -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
}