Example #1
0
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)
}
Example #2
0
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})
}
Example #3
0
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)
}