-
-
Notifications
You must be signed in to change notification settings - Fork 243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Partial claim verification #212
Comments
Hmm, the docs are lacking in this area, thanks for bringing this up! When I built on top of jwt-cpp (v0.5.0), I had two application requirements
The first was easy, I was already using RapidJSON to do that. We now have Line 3012 in 9d1a010
However only the "top level" claims are passed to the verifier, https://github.com/Thalhammer/jwt-cpp/blob/master/include/jwt-cpp/jwt.h#L3299 That's likely the best way to
Hopefully that helps answer your questions 🤞 |
Thanks! With these hints I was able to successfully create my custom validator. During my work I found few issues. They do not block me, but it would be nice if you could address them in the future:
|
I have noticed one more issue: error message for exception (returned by |
I agree that this would be helpfull, but thats hard to do. The way it works is that jwt-cpp builds a |
Custom exception class derived from |
Hmm 🤔 that's very odd.... https://github.com/Thalhammer/jwt-cpp/runs/5156063246?check_suite_focus=true#step:7:10
That explains above, it made for the default choice of picojson! Did you try including https://github.com/Thalhammer/jwt-cpp/blob/master/include/jwt-cpp/traits/nlohmann-json/defaults.h?
This is a really interesting point! Feel free to open a new issue so we can track that idea 🙏
If you can share you code, I would love to turn it into an example! |
Thank you so much for the feedback, I am glad there was just enough flexibility to keep you moving forward 🚀 |
Thanks, this helped and provided new default traits in most places. I still had to specify it for
Will do.
Here you are. It is mostly copy/paste of your examples. My code uses #include <jwt-cpp/traits/nlohmann-json/defaults.h>
#include <iostream>
int main()
{
std::string rsa_priv_key = R"(-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4ZtdaIrd1BPIJ
tfnF0TjIK5inQAXZ3XlCrUlJdP+XHwIRxdv1FsN12XyMYO/6ymLmo9ryoQeIrsXB
XYqlET3zfAY+diwCb0HEsVvhisthwMU4gZQu6TYW2s9LnXZB5rVtcBK69hcSlA2k
ZudMZWxZcj0L7KMfO2rIvaHw/qaVOE9j0T257Z8Kp2CLF9MUgX0ObhIsdumFRLaL
DvDUmBPr2zuh/34j2XmWwn1yjN/WvGtdfhXW79Ki1S40HcWnygHgLV8sESFKUxxQ
mKvPUTwDOIwLFL5WtE8Mz7N++kgmDcmWMCHc8kcOIu73Ta/3D4imW7VbKgHZo9+K
3ESFE3RjAgMBAAECggEBAJTEIyjMqUT24G2FKiS1TiHvShBkTlQdoR5xvpZMlYbN
tVWxUmrAGqCQ/TIjYnfpnzCDMLhdwT48Ab6mQJw69MfiXwc1PvwX1e9hRscGul36
ryGPKIVQEBsQG/zc4/L2tZe8ut+qeaK7XuYrPp8bk/X1e9qK5m7j+JpKosNSLgJj
NIbYsBkG2Mlq671irKYj2hVZeaBQmWmZxK4fw0Istz2WfN5nUKUeJhTwpR+JLUg4
ELYYoB7EO0Cej9UBG30hbgu4RyXA+VbptJ+H042K5QJROUbtnLWuuWosZ5ATldwO
u03dIXL0SH0ao5NcWBzxU4F2sBXZRGP2x/jiSLHcqoECgYEA4qD7mXQpu1b8XO8U
6abpKloJCatSAHzjgdR2eRDRx5PMvloipfwqA77pnbjTUFajqWQgOXsDTCjcdQui
wf5XAaWu+TeAVTytLQbSiTsBhrnoqVrr3RoyDQmdnwHT8aCMouOgcC5thP9vQ8Us
rVdjvRRbnJpg3BeSNimH+u9AHgsCgYEA0EzcbOltCWPHRAY7B3Ge/AKBjBQr86Kv
TdpTlxePBDVIlH+BM6oct2gaSZZoHbqPjbq5v7yf0fKVcXE4bSVgqfDJ/sZQu9Lp
PTeV7wkk0OsAMKk7QukEpPno5q6tOTNnFecpUhVLLlqbfqkB2baYYwLJR3IRzboJ
FQbLY93E8gkCgYB+zlC5VlQbbNqcLXJoImqItgQkkuW5PCgYdwcrSov2ve5r/Acz
FNt1aRdSlx4176R3nXyibQA1Vw+ztiUFowiP9WLoM3PtPZwwe4bGHmwGNHPIfwVG
m+exf9XgKKespYbLhc45tuC08DATnXoYK7O1EnUINSFJRS8cezSI5eHcbQKBgQDC
PgqHXZ2aVftqCc1eAaxaIRQhRmY+CgUjumaczRFGwVFveP9I6Gdi+Kca3DE3F9Pq
PKgejo0SwP5vDT+rOGHN14bmGJUMsX9i4MTmZUZ5s8s3lXh3ysfT+GAhTd6nKrIE
kM3Nh6HWFhROptfc6BNusRh1kX/cspDplK5x8EpJ0QKBgQDWFg6S2je0KtbV5PYe
RultUEe2C0jYMDQx+JYxbPmtcopvZQrFEur3WKVuLy5UAy7EBvwMnZwIG7OOohJb
vkSpADK6VPn9lbqq7O8cTedEHttm6otmLt8ZyEl3hZMaL3hbuRj6ysjmoFKx6CrX
rK0/Ikt5ybqUzKCMJZg2VKGTxg==
-----END PRIVATE KEY-----)";
auto testRoleClaim = nlohmann::json{
{"my-service", {
{"roles", { "foo", "bar", "baz" }}
}}
};
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWT")
.set_id("rsa-create-example")
.set_issued_at(std::chrono::system_clock::now())
.set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds{36000})
.set_payload_claim("resource_access", testRoleClaim)
.sign(jwt::algorithm::rs256("", rsa_priv_key, "", ""));
std::cout << "token:\n" << token << std::endl;
std::string rsa_pub_key = R"(-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuGbXWiK3dQTyCbX5xdE4
yCuYp0AF2d15Qq1JSXT/lx8CEcXb9RbDddl8jGDv+spi5qPa8qEHiK7FwV2KpRE9
83wGPnYsAm9BxLFb4YrLYcDFOIGULuk2FtrPS512Qea1bXASuvYXEpQNpGbnTGVs
WXI9C+yjHztqyL2h8P6mlThPY9E9ue2fCqdgixfTFIF9Dm4SLHbphUS2iw7w1JgT
69s7of9+I9l5lsJ9cozf1rxrXX4V1u/SotUuNB3Fp8oB4C1fLBEhSlMcUJirz1E8
AziMCxS+VrRPDM+zfvpIJg3JljAh3PJHDiLu902v9w+Iplu1WyoB2aPfitxEhRN0
YwIDAQAB
-----END PUBLIC KEY-----)";
auto decoded = jwt::decode(token);
for (const auto& e : decoded.get_payload_claims())
std::cout << e.first << " = " << e.second << std::endl;
std::cout << std::endl;
auto roleVerifier = [](const jwt::verify_ops::verify_context<jwt::traits::nlohmann_json>& ctx, std::error_code& ec)
{
auto c = ctx.get_claim(false, ec);
if (ec)
return;
if (c.get_type() == jwt::json::type::object)
{
auto obj = c.to_json();
try
{
auto roles = obj["my-service"]["roles"].get<nlohmann::json::array_t>();
if (roles.end() == std::find(roles.begin(), roles.end(), "foo"))
ec = jwt::error::token_verification_error::claim_value_missmatch;
}
catch (const std::exception& ex)
{
ec = jwt::error::token_verification_error::claim_value_missmatch;
}
}
else
ec = jwt::error::token_verification_error::claim_type_missmatch;
};
auto verifier = jwt::verify()
.allow_algorithm(jwt::algorithm::rs256(rsa_pub_key, "", "", ""))
.with_issuer("auth0")
.with_claim("resource_access", roleVerifier);
try
{
verifier.verify(decoded);
std::cout << "Success!" << std::endl;
}
catch (const std::exception& ex)
{
std::cout << "Error: " << ex.what() << std::endl;
}
return 0;
} |
Thank you so much! Hopefully in the coming weeks we can fold in your suggestions 🤗 |
Sorry to comment on this old issue, I'm just wondering about one thing that you mentioned here:
I was just wondering if this library supports using rapidjson as the json parser using the json traits, I was trying to find some info and found this other issue which seems to suggest it isn't supported: But then also found your comment above which seems to suggest that you were using rapidjson? Were you using rapidjson as the parser for jwt-cpp using the traits, or do you just mean you were using it separately just taking the json and parsing it again using rapidjson or something like that? |
Ughs 4 jobs ago... 🤔 The later. We used picojson with jwt-cpp and Marshalled the data back and forth to use it with rapidjson for schema validation. Rapidjson could be used with jwt-cpp, the effort required probably isn't worth it. Its likely just as much work to switch for another json library. |
Thanks for the reply, just wanted to check, yeah, we'll just use another library for use with jwt-cpp then. |
Describe the impediment
RedHat SSO allows configuration of roles for given service. When service gets its JWT token from SSO, it contains following claim with these roles:
Trying to obtain
I need to verify that service called "my-service" has role "bar", and ignore any other roles present in this claim. I found example where custom claim value is checked against JSON object, but this is not exactly my case - I need to check for this JSON structure ("resource_access", "my-service", "roles" elements) and verify that roles array contains proper element. Is there a way to do this using
.with_claim("resource_access", ...)
? Or do I have to useverifier.verify()
first, and then manually extract and verify this claim piece by piece?Desktop:
The text was updated successfully, but these errors were encountered: