Это плохая идея для кэширования auth0 JWK - PullRequest
0 голосов
/ 26 августа 2018

Я использую auth0, и у меня есть два клиента (ios, реагировать) и Go Backend API, использующий go-auth0 .

Я следовал документации и сделал Verify метод, который выглядит следующим образом:

func Verify(handle httprouter.Handle) httprouter.Handle {
    return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
        auth0Domain := viper.GetString("auth0.issuer")
        audience := []string{viper.GetString("auth0.audience")}

        client := auth0.NewJWKClient(auth0.JWKClientOptions{URI: auth0Domain + ".well-known/jwks.json"}, nil)
        configuration := auth0.NewConfiguration(client, audience, auth0Domain, jose.RS256)
        validator := auth0.NewValidator(configuration, nil)
        _, err := validator.ValidateRequest(r)
        if err != nil {
            w.Header().Set("Content-Type", "application/json")
            w.WriteHeader(http.StatusUnauthorized)
            json.NewEncoder(w).Encode(map[string]string{"error": "Unauthorized"})
            return
        }

        handle(w, r, p)
    }
}

К сожалению, я замечаю, что первая проверка занимает ~ 400 мс, а последующие - ~ 50 мс.

Однако, если я инициализирую структуру с полем для валидатора, перемещаю весь установочный код в Initialize(), тогда это займет всего ~ 1 мс:

func Verify(handle httprouter.Handle) httprouter.Handle {
    return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

        _, err := a.validator.ValidateRequest(r)
        if err != nil {
            w.Header().Set("Content-Type", "application/json")
            w.WriteHeader(http.StatusUnauthorized)
            json.NewEncoder(w).Encode(map[string]string{"error": "Unauthorized"})
            return
        }

        handle(w, r, p)
    }
}

Это плохая идея? Я только что узнал о JWK сегодня и смотрю на код auth0, кажется, они создают кеш, но я не совсем понимаю, как он работает.

Может кто-нибудь сообщить мне, если перенос конфигурации в структуру и использование ее валидатора - это хорошая идея?

UPDATE

У auth0 есть встроенный метод для этого! Вот пример:

auth0.NewJWKClientWithCache(auth0.JWKClientOptions{URI: a.issuer + ".well-known/jwks.json"}, nil, auth0.NewMemoryKeyCacher(time.Duration(10)*time.Second, 5))

Используйте этот метод, чтобы он кешировал для вас! :)

1 Ответ

0 голосов
/ 26 августа 2018

Почти наверняка должно быть безопасно кешировать объект клиента, и в целом это, как правило, хорошая идея.(«Создайте одного клиента и используйте его повторно» - это хорошее общее правило.)

Насколько я понимаю, ключи подписи для JWT обычно действительны в течение нескольких месяцев, если не дольше.( Документация Auth0 отмечает , что в его документах JWKS всегда есть только один ключ, но он будет выдавать подписанные токены все время, поэтому ключи должны быть действительны в течение некоторого времени.) RFC 7517 не определяет никаких параметров, связанных с истечением срока действия, ни в JWKS, ни в отдельном JWK, и я думаю, что лучше всего использовать обычные элементы управления HTTP-кэшированием в конечной точке JWKS, чтобы периодически обновлять его, но не так часто.

...