Thalhammer / jwt-cpp

A header only library for creating and validating json web tokens in c++
https://thalhammer.github.io/jwt-cpp/
MIT License
855 stars 233 forks source link

JWKS caching question #289

Closed iherbig closed 4 months ago

iherbig commented 1 year ago

What's your question?

Is it expected that jwt::jwks can't be cached?

Additional Context

As far as I understand, relying parties are expected to cache retrieved key sets indefinitely (or until a kid is seen which is not present in the key set). I've been forced to cache the raw JSON and re-parse with jwt::parse_jwks every time a request comes in because attempting to cache the parsed jwt::jwks fails to compile with an error indicating that the underlying jwt::jwk is non-copyable.

This:

auto jwks = jwt::parse_jwks(jwksJson);
std::map<std::string, jwt::jwks<jwt::traits::kazuho_picojson>> xs;
xs[issuerUrl] = jwks;

Results in this:

15>C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\vector(1485,27): error C2280: 'jwt::jwk<jwt::traits::kazuho_picojson> &jwt::jwk<jwt::traits::kazuho_picojson>::operator =(const jwt::jwk<jwt::traits::kazuho_picojson> &)': attempting to reference a deleted function
15>\libraries\jwt-cpp\jwt.h(3565,1): message : compiler has generated 'jwt::jwk<jwt::traits::kazuho_picojson>::operator =' here
15>\libraries\jwt-cpp\jwt.h(3565,1): message : 'jwt::jwk<jwt::traits::kazuho_picojson> &jwt::jwk<jwt::traits::kazuho_picojson>::operator =(const jwt::jwk<jwt::traits::kazuho_picojson> &)': function was implicitly deleted because a data member 'jwt::jwk<jwt::traits::kazuho_picojson>::jwk_claims' has either no appropriate copy assignment operator or overload resolution was ambiguous
15>\libraries\jwt-cpp\jwt.h(3373,45): message : see declaration of 'jwt::jwk<jwt::traits::kazuho_picojson>::jwk_claims'
15>C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\vector(1561,1): message : see reference to function template instantiation 'void std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>>::_Assign_counted_range<jwt::jwk<jwt::traits::kazuho_picojson>*>(_Iter,const unsigned __int64)' being compiled
15>        with
15>        [
15>            _Iter=jwt::jwk<jwt::traits::kazuho_picojson> *
15>        ]
15>C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\vector(1561,30): message : see reference to function template instantiation 'void std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>>::_Assign_counted_range<jwt::jwk<jwt::traits::kazuho_picojson>*>(_Iter,const unsigned __int64)' being compiled
15>        with
15>        [
15>            _Iter=jwt::jwk<jwt::traits::kazuho_picojson> *
15>        ]
15>C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\vector(1545,1): message : while compiling class template member function 'std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>> &std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>>::operator =(const std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>> &)'
15>\libraries\jwt-cpp\jwt.h(3632,1): message : see reference to function template instantiation 'std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>> &std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>>::operator =(const std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>> &)' being compiled
15>\libraries\jwt-cpp\jwt.h(3582,1): message : see reference to class template instantiation 'std::vector<jwt::jwk<jwt::traits::kazuho_picojson>,std::allocator<jwt::jwk<jwt::traits::kazuho_picojson>>>' being compiled
15>\libraries\jwt-cpp\traits\kazuho-picojson\defaults.h(73,101): message : see reference to class template instantiation 'jwt::jwks<jwt::traits::kazuho_picojson>' being compiled

Is this a case of me missing something obvious? Or is this actually an issue?

prince-chrismc commented 1 year ago

It's been awhile but you understanding seems correct, why not just move it? I guess my question is why do you need copies?

My expectations is that it would be saved in an object and you could move it to the member variable and just reference that?

Does that not fit you use case?

Thalhammer commented 1 year ago

Copying can very often be a required thing to do (especially in multithreaded code), so it definitely should be possible.

Looking at the error it seems like it fails to copy the claims member in jwk_claims, which is of type map_of_claims, which is really just a wrapper around the json_traits::object_type however both picojson::value and map_of_claims have a copy constructor, so I don't quite get why msvc complains.

EDIT: I added a copy to one of the test cases and it compiles fine in both clang/gcc, so I am not sure what msvc is up to here.

prince-chrismc commented 4 months ago

I assume you solved this but there is some example code in https://github.com/Thalhammer/jwt-cpp/pull/345 about how this could be done