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) Granted(ctx context.Context, rw http.ResponseWriter, req *http.Request) { auth, err := osin.CheckBasicAuth(req) if err != nil { pkg.HttpError(rw, errors.New("Unauthorized"), http.StatusUnauthorized) return } else if auth == nil { pkg.HttpError(rw, errors.New("Unauthorized"), http.StatusUnauthorized) return } client, err := h.o.GetClient(auth.Username) if err != nil { pkg.HttpError(rw, errors.New("Unauthorized"), http.StatusUnauthorized) return } else if client.GetSecret() != auth.Password { pkg.HttpError(rw, errors.New("Unauthorized"), http.StatusUnauthorized) return } var p GrantedPayload decoder := json.NewDecoder(req.Body) if err := decoder.Decode(&p); err != nil { pkg.HttpError(rw, errors.New(err), http.StatusBadRequest) return } token, err := h.j.VerifyToken([]byte(p.Token)) if err != nil { log.WithFields(log.Fields{ "error": err.Error(), "resource": p.Resource, "permission": p.Permission, "subject": "", "context": fmt.Sprintf("%s", p.Context), }).Warn("Token not valid.") pkg.WriteJSON(rw, struct { Allowed bool `json:"allowed"` Error string `json:"error"` }{Allowed: false, Error: err.Error()}) return } subject, ok := token.Claims["sub"].(string) if !ok { err := errors.New("Bearer token is not valid.") log.WithFields(log.Fields{ "error": err.Error(), "resource": p.Resource, "permission": p.Permission, "subject": "", "context": fmt.Sprintf("%s", p.Context), }).Warn("Token does not claim a subject.") pkg.WriteJSON(rw, struct { Allowed bool `json:"allowed"` Error string `json:"error"` }{Allowed: false, Error: err.Error()}) return } policies, err := h.s.FindPoliciesForSubject(subject) if err != nil { log.WithFields(log.Fields{ "error": err.Error(), "resource": p.Resource, "permission": p.Permission, "subject": subject, "context": fmt.Sprintf("%s", p.Context), }).Warn("Could not fetch policies from store.") pkg.WriteJSON(rw, struct { Allowed bool `json:"allowed"` Error string `json:"error"` }{Allowed: false, Error: err.Error()}) return } allowed, err := h.g.IsGranted(p.Resource, p.Permission, subject, policies, p.Context) if err != nil { log.WithFields(log.Fields{ "error": err.Error(), "resource": p.Resource, "permission": p.Permission, "subject": subject, "policies": fmt.Sprintf("%s", policies), "context": fmt.Sprintf("%s", p.Context), }).Warn("Granted check failed.") pkg.WriteJSON(rw, struct { Allowed bool `json:"allowed"` Error string `json:"error"` }{Allowed: false, Error: err.Error()}) return } log.WithFields(log.Fields{ "resource": p.Resource, "permission": p.Permission, "subject": subject, "allowed": allowed, "policies": fmt.Sprintf("%s", policies), "context": fmt.Sprintf("%s", p.Context), }).Info("Got guard decision.") pkg.WriteJSON(rw, struct { Allowed bool `json:"allowed"` }{Allowed: allowed}) }
func (h *Handler) RevokeHandler(w http.ResponseWriter, r *http.Request) { auth, err := osin.CheckBasicAuth(r) if 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 } r.ParseForm() tokenToRevoke := r.Form.Get("token") if tokenToRevoke == "" { log.WithField("revokation", "fail").Warn("No token given.") pkg.HttpError(w, errors.New("No token given"), http.StatusServiceUnavailable) return } getClaims := func(ud interface{}) (jwt.ClaimsCarrier, error) { data, ok := ud.(string) var claims jwt.ClaimsCarrier if !ok { return nil, errors.New("Could not assert UserData to string") } if err := json.Unmarshal([]byte(data), &claims); err != nil { return nil, errors.New("Could not unmarshal UserData") } return claims, nil } var ud interface{} var revokeToken *osin.AccessData if revokeToken, err = h.OAuthStore.LoadAccess(tokenToRevoke); err == pkg.ErrNotFound { revokeToken, err = h.OAuthStore.LoadRefresh(tokenToRevoke) if err != nil { log.WithField("revokation", "fail").WithField("error", err).Warn("Could not fetch refresh token.") pkg.HttpError(w, errors.New("Could not find token"), http.StatusServiceUnavailable) return } } else if err != nil { log.WithField("revokation", "fail").WithField("error", err).Warn("Could not fetch acccess token.") pkg.HttpError(w, errors.New("Could not find token"), http.StatusServiceUnavailable) return } ud = revokeToken.UserData claims, err := getClaims(ud) if err != nil { log.WithField("error", err).Warn("Could not retrieve claims.") pkg.HttpError(w, err, http.StatusServiceUnavailable) return } if claims.GetAudience() != client.GetId() { log.WithFields(log.Fields{ "claimAudience": claims.GetAudience(), "clientAudience": client.GetId(), }).Warn("Suspicious activity detected. Audience mismatch.") pkg.HttpError(w, errors.New("Forbidden"), http.StatusServiceUnavailable) return } if err := h.OAuthStore.RemoveAccess(revokeToken.AccessToken); err != nil { log.WithField("error", err).Warn("Could not revoke access token.") pkg.HttpError(w, err, http.StatusServiceUnavailable) return } w.WriteHeader(http.StatusOK) }