func (h *Handler) IntrospectHandler(w http.ResponseWriter, r *http.Request) { auth, err := osin.CheckBasicAuth(r) if _, err := h.OAuthStore.GetClient(auth.Username); err != nil { pkg.HttpError(w, errors.New("Unauthorized"), http.StatusUnauthorized) return } else if auth == nil { pkg.HttpError(w, errors.New("Unauthorized"), http.StatusUnauthorized) return } client, err := h.OAuthStore.GetClient(auth.Username) if err != nil { pkg.HttpError(w, errors.New("Unauthorized"), http.StatusUnauthorized) return } else if client.GetSecret() != auth.Password { pkg.HttpError(w, errors.New("Unauthorized"), http.StatusUnauthorized) return } result := make(map[string]interface{}) result["active"] = false r.ParseForm() if r.Form.Get("token") == "" { log.WithField("introspect", "fail").Warn("No token given.") result["error"] = "No token given." pkg.WriteJSON(w, result) return } token, err := h.JWT.VerifyToken([]byte(r.Form.Get("token"))) if err != nil { log.WithField("introspect", "fail").Warn("Token is invalid.") pkg.WriteJSON(w, result) return } claims := jwt.ClaimsCarrier(token.Claims) if claims.GetAudience() != auth.Username { log.WithFields(log.Fields{ "introspect": "fail", "actualAudience": auth.Username, "expectedAudience": claims.GetAudience(), }).Warn(`Token audience mismatch.`) pkg.WriteJSON(w, result) return } if claims.GetSubject() == "" { log.WithFields(log.Fields{ "introspect": "fail", }).Warn(`Token claims no subject.`) pkg.WriteJSON(w, result) return } result = token.Claims result["active"] = token.Valid pkg.WriteJSON(w, result) }
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) IntrospectHandler(w http.ResponseWriter, r *http.Request) { r.ParseForm() bearer := osin.CheckBearerAuth(r) if bearer == nil { log.WithField("introspect", "fail").Warn("No authorization header given.") http.Error(w, "No bearer given.", http.StatusUnauthorized) return } else if bearer.Code == "" { log.WithField("introspect", "fail").Warn("No authorization bearer is empty.") http.Error(w, "No bearer token given.", http.StatusUnauthorized) return } token, err := h.JWT.VerifyToken([]byte(bearer.Code)) if err != nil { log.WithField("introspect", "fail").Warn("Bearer token is invalid.") http.Error(w, "Bearer token is not valid.", http.StatusForbidden) return } result := token.Claims defer func() { out, err := json.Marshal(result) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.Write(out) }() result["active"] = false claims := jwt.ClaimsCarrier(token.Claims) if claims.GetAudience() != h.Audience { log.WithFields(log.Fields{ "introspect": "fail", "expted": h.Audience, "actual": claims.GetAudience(), }).Warn(`Token audience mismatch.`) return } else { result["active"] = token.Valid return } }
func NewContextFromAuthorization(ctx context.Context, req *http.Request, j *hjwt.JWT, p policy.Storage) context.Context { bearer := osin.CheckBearerAuth(req) if bearer == nil { log.Warn("No authorization bearer given.") return NewContextFromAuthValues(ctx, nil, nil, nil) } t, err := j.VerifyToken([]byte(bearer.Code)) if err != nil { log.Warnf(`Token validation errored: "%v".`, err) return NewContextFromAuthValues(ctx, nil, nil, nil) } else if !t.Valid { log.Warn("Token is invalid.") return NewContextFromAuthValues(ctx, nil, nil, nil) } claims := hjwt.ClaimsCarrier(t.Claims) user := claims.GetSubject() if user == "" { log.Warnf(`sub claim may not be empty, to: "%v".`, t.Claims) return NewContextFromAuthValues(ctx, nil, nil, nil) } policies, err := p.FindPoliciesForSubject(user) if err != nil { log.Warnf(`Policies for "%s" could not be retrieved: "%v"`, user, err) return NewContextFromAuthValues(ctx, nil, nil, nil) } // user, err := s.Get(id) // if err != nil { // log.Warnf("Subject not found in store: %v %v", t.Claims, err) // return NewContextFromAuthValues(ctx, nil, nil, nil) // } return NewContextFromAuthValues(ctx, claims, t, policies) }