jsonb-api
jsonb-api copied to clipboard
ES6 Compatible Parsing & Serialization
ES6 (EcmaScript version 6) and forward specifies very specific rules for serialization including "predictive property" order. This may appear strange but for a human creating the properties A, B, C and getting them serialized as A, C, B is slightly awkward, although completely compatible with JSON.
In addition, ES6 also specifies strict rules for serializing numbers which are quite different from what native Java does.
Anyway, a huge advantage with ES6 parsing and serialization is that it makes it possible creating very elegant "crypto safe" objects as described here: https://cyberphone.github.io/doc/security/jsonsignatures.html
This is currently supported by an open source library of mine (https://github.com/cyberphone/openkeystore#openkeystore) but it would be even cooler if ES6 compatible parsing and serialization would be a part of JSON-B or at least of your reference implementation. This should be coordinated with your JavaScript engine since the very same scheme must be running there already.
- Issue Imported From: https://github.com/javaee/jsonb-spec/issues/50
- Original Issue Raised By:@cyberphone
- Original Issue Assigned To: Unassigned
@rmannibucau Commented Default is the lexicographic order. However you can use https://github.com/javaee/jsonb-spec/blob/master/api/src/main/java/javax/json/bind/annotation/JsonbPropertyOrder.java to fit your need.
@cyberphone Commented This issue is actually a bit flawed (dated) because ES6 compatible JSON serialization consists of two entirely different things:
- Serialization of JSON primitives (Numbers, Literals, and Strings)
- Property ordering (which also affects parsing)
https://tools.ietf.org/id/draft-erdtman-jose-cleartext-jws-00.html depends on both features.
Predictive property ordering a la ES6 requires something like: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html. Is that achievable through the various Java/JSON APIs? Bear with me, I'm unarguable NOT an expert on those.
JSON Number serialization is an awkward chapter, not even JDK's JavaScript engine (Nashorn) follows the ECMAScript standard. MSFT is currently working on getting their counterpart ES6 compatible.
@rmannibucau Commented Hmm, parsing is not (and must not actually to respect the mapping side of the spec) affected at jsonp or jsonb level since it is a bean matching which is done so we are all good.
Ordering is deterministic and predictable as mentionned in previous mail and should in any case be enforced by the user if needed with the related API (order annotation).
The primitive serialization is handled by json-p accoring to json spec.
@cyberphone Commented For enveloped clear text signatures based on ES6 rules, parsing and serialization are closely intertwined. In retrospect I've noted that this complicates the implementation in many JSON APIs, which is why I nowadays rather advocate for using traditional canonicalization, like in XML DSig but way simpler: https://cyberphone.github.io/doc/security/draft-rundgren-json-canonicalization-scheme.html
It would be interesting hearing your opinion on this matter because a draft is just a draft :-)
@rmannibucau Commented I strongly think we can't change the defaults since they really match today's way of working. However JSON-P (I don't think JSON-B is affected) can get a flag you pass to the generator factory to normalize the data. Would make sense. Then JSON-B would just passtrough the flag.
@cyberphone Commented
I strongly think we can't change the defaults since they really match today's way of working
For my poor understanding only: Does this mean that the Java APIs in question by default are unable parsing JSON Numbers or JSON Strings produced by Browsers and Node.js?
@rmannibucau Commented No, it works well. It just means that normalizing everything is not good since current representation - which is stable/deterministic - is already in used and what is used and mainstream.
@cyberphone Commented That was what I expected. This also means that if the serialization API (JSON-P?) would be enhanced with ES6 compliant serialization of Strings and Numbers (for ints, floats and doubles only NB) as default, nothing would/should change/break with respect to the User Community. Such code is readily available.
The remaining hurdle (property ordering), would in your case already be fixed (-minus some minor spec work) if the IETF signature scheme in the workings, would be revised to rather depend of lexicographic than on predictive ordering.
Well, there is this I-JSON thing as well, but as shown by the following Twitter message
{"id": 10765432100123456789, "id_str": "10765432100123456789", ...}
the industry have already found "solutions" 😂
@cyberphone Commented Oops! I just found a (for the mentioned application only) breaking issue:
4.2 Customizing Property Order To customize the order of serialized properties only for one specific type, JSON Binding provides javax.json.bind.annotation.JsonbPropertyOrder annotation. Order specified by JsonbPropertyOrder annotation overrides order specified by PropertyOrderStrategy
Here is the "problem": https://cyberphone.github.io/doc/security/draft-rundgren-json-canonicalization-scheme.html#json.wireformat
@cyberphone Commented After chatting with @rmannibucau on IRC it became clear that changing default serialization of numbers to match ES6 is unrealistic since there are systems out there relying on JSON-P's specific formatting.
That effectively leaves us (me) with a single option: Add an item CANONICALIZED to the PropertyOrderStrategy set which implies the following:
- Unconditionally serialize properties in LEXICOGRAPHIC order
- Use ES6 compatible Number and String formatting