func TestGetters(t *testing.T) { assert.False(t, IsAuthenticatedFromContext(context.Background())) _, err := PoliciesFromContext(context.Background()) assert.NotNil(t, err) _, err = SubjectFromContext(context.Background()) assert.NotNil(t, err) _, err = TokenFromContext(context.Background()) assert.NotNil(t, err) ctx := context.Background() claims := hjwt.ClaimsCarrier{"sub": "peter"} token := &jwt.Token{Valid: true} policies := []policy.Policy{} ctx = NewContextFromAuthValues(ctx, claims, token, policies) assert.True(t, IsAuthenticatedFromContext(ctx)) policiesContext, err := PoliciesFromContext(ctx) assert.Nil(t, err) assert.Equal(t, policies, policiesContext) subjectContext, err := SubjectFromContext(ctx) assert.Nil(t, err) assert.Equal(t, claims.GetSubject(), subjectContext) tokenContext, err := TokenFromContext(ctx) assert.Nil(t, err) assert.Equal(t, token, tokenContext) }
func (h *Handler) TokenHandler(w http.ResponseWriter, r *http.Request) { resp := h.server.NewResponse() r.ParseForm() defer resp.Close() if ar := h.server.HandleAccessRequest(resp, r); ar != nil { switch ar.Type { case osin.AUTHORIZATION_CODE: data, ok := ar.UserData.(string) if !ok { http.Error(w, fmt.Sprintf("Could not assert UserData to string: %v", ar.UserData), http.StatusInternalServerError) return } var claims jwt.ClaimsCarrier if err := json.Unmarshal([]byte(data), &claims); err != nil { http.Error(w, fmt.Sprintf("Could not unmarshal UserData: %v", ar.UserData), http.StatusInternalServerError) return } ar.UserData = jwt.NewClaimsCarrier(uuid.New(), claims.GetSubject(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true case osin.REFRESH_TOKEN: data, ok := ar.UserData.(map[string]interface{}) if !ok { http.Error(w, fmt.Sprintf("Could not assert UserData type: %v", ar.UserData), http.StatusInternalServerError) return } claims := jwt.ClaimsCarrier(data) ar.UserData = jwt.NewClaimsCarrier(uuid.New(), claims.GetSubject(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true case osin.PASSWORD: // TODO if !ar.Client.isAllowedToAuthenticateUser // TODO ... return // TODO } if user, err := h.authenticate(w, r, ar.Username, ar.Password); err == nil { ar.UserData = jwt.NewClaimsCarrier(uuid.New(), user.GetID(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true } case osin.CLIENT_CREDENTIALS: ar.UserData = jwt.NewClaimsCarrier(uuid.New(), ar.Client.GetId(), h.Issuer, h.Audience, time.Now(), time.Now()) ar.Authorized = true // TODO ASSERTION workflow http://leastprivilege.com/2013/12/23/advanced-oauth2-assertion-flow-why/ // TODO Since assertions are only a draft for now and there is no need for SAML or similar this is postponed. //case osin.ASSERTION: // if ar.AssertionType == "urn:hydra" && ar.Assertion == "osin.data" { // ar.Authorized = true // } } h.server.FinishAccessRequest(resp, r, ar) } if resp.IsError { resp.StatusCode = http.StatusUnauthorized } osin.OutputJSON(resp, w, r) }
func (h *Handler) TokenHandler(w http.ResponseWriter, r *http.Request) { resp := h.server.NewResponse() defer resp.Close() if ar := h.server.HandleAccessRequest(resp, r); ar != nil { switch ar.Type { case osin.AUTHORIZATION_CODE: data, ok := ar.UserData.(string) if !ok { log.WithField("UserData", fmt.Sprintf("%v", ar.UserData)).Warn("Could not assert UserData to string") } else { var claims jwt.ClaimsCarrier if err := json.Unmarshal([]byte(data), &claims); err != nil { http.Error(w, fmt.Sprintf("Could not unmarshal UserData: %v", ar.UserData), http.StatusInternalServerError) } else { ar.UserData = jwt.NewClaimsCarrier(uuid.New(), h.Issuer, claims.GetSubject(), ar.Client.GetId(), time.Now().Add(time.Duration(ar.Expiration)*time.Second), time.Now(), time.Now()) ar.Authorized = true } } case osin.REFRESH_TOKEN: data, ok := ar.UserData.(string) if !ok { http.Error(w, fmt.Sprintf("Could not assert UserData to string: %v", ar.UserData), http.StatusInternalServerError) } else { var claims jwt.ClaimsCarrier if err := json.Unmarshal([]byte(data), &claims); err != nil { http.Error(w, fmt.Sprintf("Could not unmarshal UserData: %v", ar.UserData), http.StatusInternalServerError) } else { ar.UserData = jwt.NewClaimsCarrier(uuid.New(), h.Issuer, claims.GetSubject(), ar.Client.GetId(), time.Now().Add(time.Duration(ar.Expiration)*time.Second), time.Now(), time.Now()) ar.Authorized = true } } case osin.PASSWORD: // TODO if !ar.Client.isAllowedToAuthenticateUser // TODO ... return // TODO } if user, err := h.authenticate(w, r, ar.Username, ar.Password); err == nil { ar.UserData = jwt.NewClaimsCarrier(uuid.New(), h.Issuer, user.GetID(), ar.Client.GetId(), time.Now().Add(time.Duration(ar.Expiration)*time.Second), time.Now(), time.Now()) ar.Authorized = true } case osin.CLIENT_CREDENTIALS: ar.UserData = jwt.NewClaimsCarrier(uuid.New(), h.Issuer, ar.Client.GetId(), ar.Client.GetId(), time.Now().Add(time.Duration(ar.Expiration)*time.Second), time.Now(), time.Now()) ar.Authorized = true // TODO #29 ASSERTION workflow http://leastprivilege.com/2013/12/23/advanced-oauth2-assertion-flow-why/ // Since assertions are only a draft for now and there is no need for SAML or similar this is postponed. // case osin.ASSERTION: // if ar.AssertionType == "urn:hydra" && ar.Assertion == "osin.data" { // ar.Authorized = true // } } h.server.FinishAccessRequest(resp, r, ar) } if resp.IsError { log.WithFields(log.Fields{ "code": resp.StatusCode, "id": resp.ErrorId, "message": resp.StatusText, "osinInternalError": resp.InternalError, }).Warnf("Token request failed.") resp.StatusCode = http.StatusUnauthorized } osin.OutputJSON(resp, w, r) }