From 00bdd28ef47ed1b766b01637f7256befdec4aaaf Mon Sep 17 00:00:00 2001 From: Aeneas Date: Thu, 17 Nov 2016 17:34:07 +0100 Subject: [PATCH] oauth2: resolve issues with token introspection on user tokens (#309) --- cmd/server/handler_oauth2_factory.go | 1 + docker-compose.yml | 7 +++++- glide.lock | 32 ++++++++++++++-------------- glide.yaml | 2 +- oauth2/fosite_store_sql.go | 16 ++++++++------ oauth2/handler.go | 10 ++++++++- oauth2/session.go | 17 +++++++++++++++ warden/warden_local.go | 7 +++++- 8 files changed, 66 insertions(+), 26 deletions(-) diff --git a/cmd/server/handler_oauth2_factory.go b/cmd/server/handler_oauth2_factory.go index 6a551f56e67..443f66d948c 100644 --- a/cmd/server/handler_oauth2_factory.go +++ b/cmd/server/handler_oauth2_factory.go @@ -144,6 +144,7 @@ func newOAuth2Handler(c *config.Config, router *httprouter.Router, km jwk.Manage }, ConsentURL: *consentURL, H: &herodot.JSON{}, + AccessTokenLifespan:c.GetAccessTokenLifespan(), } handler.SetRoutes(router) diff --git a/docker-compose.yml b/docker-compose.yml index ab9431f9a31..cadc0946ae2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,6 +22,9 @@ services: # Uncomment the following line to use mysql instead. # - DATABASE_URL=mysql://root:secret@tcp(mysqld:3306)/mysql?parseTime=true - FORCE_ROOT_CLIENT_CREDENTIALS=admin:demo-password + - ACCESS_TOKEN_LIFESPAN=${ACCESS_TOKEN_LIFESPAN} + - ID_TOKEN_LIFESPAN=${ID_TOKEN_LIFESPAN} + - AUTHORIZE_CODE_LIFESPAN=${AUTHORIZE_CODE_LIFESPAN} restart: unless-stopped consent: @@ -39,6 +42,8 @@ services: postgresd: image: postgres:9.6 + ports: + - "5432:5432" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=secret @@ -50,4 +55,4 @@ services: volumes: hydravolume: - driver: local \ No newline at end of file + driver: local diff --git a/glide.lock b/glide.lock index 4e592cf7f7c..583303b4e4b 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 18b2d7631e4e950d4e18b6ec76906081980e532850d32c19e414259b8293fe9a -updated: 2016-10-21T22:08:32.7305955+02:00 +hash: 0187ab27e5d927f43a0faca5d90fa8f1d3c52d5361cef95355a257c966401645 +updated: 2016-11-17T16:40:00.870214549+01:00 imports: - name: github.com/asaskevich/govalidator version: 7b3beb6df3c42abd3509abfc3bcacc0fbfb7c877 @@ -12,13 +12,13 @@ imports: - name: github.com/dgrijalva/jwt-go version: d2709f9f1f31ebcda9651b03077758c1f3a0018c - name: github.com/fsnotify/fsnotify - version: bd2828f9f176e52d7222e565abb2d338d3f3c103 + version: 944cff21b3baf3ced9a880365682152ba577d348 - name: github.com/go-errors/errors version: a41850380601eeb43f4350f7d17c6bbd8944aaf8 - name: github.com/go-sql-driver/mysql version: 0b58b37b664c21f3010e836f1b931e1d0b0b0685 - name: github.com/golang/protobuf - version: c3cefd437628a0b7d31b34fe44b3a7a540e98527 + version: df1d3ca07d2d07bba352d5b73c4313b4e2a6203e subpackages: - proto - name: github.com/hailocab/go-hostpool @@ -39,7 +39,7 @@ imports: - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 - name: github.com/jmoiron/sqlx - version: 05b81a7d5d38058e42148dc01f17daf4acba4640 + version: 5f97679e23f75f42b265fec8d3bdb1c8de90b79d subpackages: - reflectx - name: github.com/julienschmidt/httprouter @@ -47,7 +47,7 @@ imports: - name: github.com/kr/fs version: 2788f0dbd16903de03cb8186e5c7d97b69ad387b - name: github.com/lib/pq - version: ae8357db35d721c58dcdc911318b55bef6b1b001 + version: fcb9ef54da7cae1ea08f0b5a92f236d83e59294a subpackages: - oid - name: github.com/magiconair/properties @@ -68,7 +68,7 @@ imports: - pkg - rand/sequence - name: github.com/ory-am/fosite - version: eb9077f6608d776ae50eb2ad4205705bad6ee0eb + version: 895d16935bd97831eecff66b1d775af9b91a2506 subpackages: - compose - fosite-example/pkg @@ -106,13 +106,13 @@ imports: - name: github.com/spf13/cast version: 2580bc98dc0e62908119e4737030cc2fdfc45e4c - name: github.com/spf13/cobra - version: 856b96dcb49d6427babe192998a35190a12c2230 + version: 9c28e4bbd74e5c3ed7aacbc552b2cab7cfdfe744 - name: github.com/spf13/jwalterweatherman version: 33c24e77fb80341fe7130ee7c594256ff08ccc46 - name: github.com/spf13/pflag - version: bf8481a6aebc13a8aab52e699ffe2e79771f5a3f + version: b83537d79690b75cac5e021b036ae16792bf0f20 - name: github.com/spf13/viper - version: 50515b700e02658272117a72bd641b6b7f1222e5 + version: 21ea37b67349cb6594eea6eaf765b2a7b96f03e2 - name: github.com/square/go-jose version: aa2e30fdd1fe9dd3394119af66451ae790d50e0d subpackages: @@ -127,7 +127,7 @@ imports: - name: github.com/urfave/negroni version: fde5e16d32adc7ad637e9cd9ad21d4ebc6192535 - name: golang.org/x/crypto - version: e0d166c33c321d0ff863f459a5882096e334f508 + version: d172538b2cfce0c13cee31e647d0367aa8cd2486 subpackages: - bcrypt - blowfish @@ -137,25 +137,25 @@ imports: - pbkdf2 - ssh - name: golang.org/x/net - version: 075e191f18186a8ff2becaf64478e30f4545cdad + version: f4b625ec9b21d620bb5ce57f2dfc3e08ca97fce6 subpackages: - context - name: golang.org/x/oauth2 - version: 04e1573abc896e70388bd387a69753c378d46466 + version: 1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5 subpackages: - clientcredentials - internal - name: golang.org/x/sys - version: a646d33e2ee3172a661fc09bca23bb4889a41bc8 + version: 8d1157a435470616f975ff9bb013bea8d0962067 subpackages: - unix - name: golang.org/x/text - version: fa5033c827cad7080e8e7047a0091945b0e1f031 + version: ede1cb9f9f2f84c3bace9ca113fd740fc916cdd0 subpackages: - transform - unicode/norm - name: google.golang.org/appengine - version: b4728023490a62e70ba739ff62aa65ffcca84210 + version: 3f4dbbc0ec153a39878fd524ece9f39732bd4998 subpackages: - internal - internal/base diff --git a/glide.yaml b/glide.yaml index 1abe7b432ff..a0858ef0df8 100644 --- a/glide.yaml +++ b/glide.yaml @@ -18,7 +18,7 @@ import: - package: github.com/dgrijalva/jwt-go version: ~3.0.0 - package: github.com/ory-am/fosite - version: ~0.5.0 + version: ~0.6.1 subpackages: - compose - fosite-example/pkg diff --git a/oauth2/fosite_store_sql.go b/oauth2/fosite_store_sql.go index 834ec22ab96..337e89b30a1 100644 --- a/oauth2/fosite_store_sql.go +++ b/oauth2/fosite_store_sql.go @@ -87,10 +87,12 @@ func sqlSchemaFromRequest(signature string, r fosite.Requester) (*sqlData, error } func (s *sqlData) ToRequest(session fosite.Session, cm client.Manager) (*fosite.Request, error) { - if session != nil { - if err := json.Unmarshal(s.Session, session); err != nil { - return nil, errors.Wrap(err, "") - } + if session == nil { + return nil, errors.New("Session undefined") + } + + if err := json.Unmarshal(s.Session, session); err != nil { + return nil, errors.Wrap(err, "") } c, err := cm.GetClient(s.Client) @@ -103,7 +105,7 @@ func (s *sqlData) ToRequest(session fosite.Session, cm client.Manager) (*fosite. return nil, errors.Wrap(err, "") } - return &fosite.Request{ + r := &fosite.Request{ ID: s.Request, RequestedAt: s.RequestedAt, Client: c, @@ -111,7 +113,9 @@ func (s *sqlData) ToRequest(session fosite.Session, cm client.Manager) (*fosite. GrantedScopes: fosite.Arguments(strings.Split(s.GrantedScopes, "|")), Form: val, Session: session, - }, nil + } + + return r, nil } func (s *FositeSQLStore) createSession(signature string, requester fosite.Requester, table string) error { diff --git a/oauth2/handler.go b/oauth2/handler.go index 847376d6c8b..d88cc2f8fa1 100644 --- a/oauth2/handler.go +++ b/oauth2/handler.go @@ -11,6 +11,7 @@ import ( "github.com/ory-am/hydra/pkg" "github.com/pkg/errors" "strings" + "time" ) const ( @@ -33,6 +34,8 @@ type Handler struct { ForcedHTTP bool ConsentURL url.URL + + AccessTokenLifespan time.Duration } func (h *Handler) SetRoutes(r *httprouter.Router) { @@ -57,6 +60,7 @@ func (h *Handler) RevocationHandler(w http.ResponseWriter, r *http.Request, _ ht func (h *Handler) IntrospectHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var session = NewSession("") + var ctx = fosite.NewContext() resp, err := h.OAuth2.NewIntrospectionRequest(ctx, r, session) if err != nil { @@ -70,11 +74,15 @@ func (h *Handler) IntrospectHandler(w http.ResponseWriter, r *http.Request, _ ht return } + exp := resp.GetAccessRequester().GetSession().GetExpiresAt(fosite.AccessToken) + if exp.IsZero() { + exp = resp.GetAccessRequester().GetRequestedAt().Add(h.AccessTokenLifespan) + } _ = json.NewEncoder(w).Encode(&Introspection{ Active: true, ClientID: resp.GetAccessRequester().GetClient().GetID(), Scope: strings.Join(resp.GetAccessRequester().GetGrantedScopes(), " "), - ExpiresAt: resp.GetAccessRequester().GetSession().GetExpiresAt(fosite.AccessToken).Unix(), + ExpiresAt: exp.Unix(), IssuedAt: resp.GetAccessRequester().GetRequestedAt().Unix(), Subject: resp.GetAccessRequester().GetSession().GetSubject(), Username: resp.GetAccessRequester().GetSession().GetUsername(), diff --git a/oauth2/session.go b/oauth2/session.go index 397a4760a00..ae82d41a1d9 100644 --- a/oauth2/session.go +++ b/oauth2/session.go @@ -3,6 +3,9 @@ package oauth2 import ( "github.com/ory-am/fosite/handler/openid" "github.com/ory-am/fosite/token/jwt" + "github.com/ory-am/fosite" + "bytes" + "encoding/gob" ) type Session struct { @@ -19,3 +22,17 @@ func NewSession(subject string) *Session { }, } } + +func (s *Session) Clone() fosite.Session { + if s == nil { + return nil + } + + var clone Session + var mod bytes.Buffer + enc := gob.NewEncoder(&mod) + dec := gob.NewDecoder(&mod) + _ = enc.Encode(s) + _ = dec.Decode(&clone) + return &clone +} \ No newline at end of file diff --git a/warden/warden_local.go b/warden/warden_local.go index b7e244fa87f..dce4e9b33f5 100644 --- a/warden/warden_local.go +++ b/warden/warden_local.go @@ -81,13 +81,18 @@ func (w *LocalWarden) sessionAllowed(ctx context.Context, a *firewall.TokenAcces func (w *LocalWarden) newContext(oauthRequest fosite.AccessRequester) *firewall.Context { session := oauthRequest.GetSession().(*oauth2.Session) + + exp := oauthRequest.GetSession().GetExpiresAt(fosite.AccessToken) + if exp.IsZero() { + exp = oauthRequest.GetRequestedAt().Add(w.AccessTokenLifespan) + } c := &firewall.Context{ Subject: session.Subject, GrantedScopes: oauthRequest.GetGrantedScopes(), Issuer: w.Issuer, Audience: oauthRequest.GetClient().GetID(), IssuedAt: oauthRequest.GetRequestedAt(), - ExpiresAt: session.GetExpiresAt(fosite.AccessToken), + ExpiresAt: exp, Extra: session.Extra, }