1313import org .apache .avro .Schema ;
1414import org .apache .avro .SchemaBuilder ;
1515import org .apache .avro .file .DataFileStream ;
16+ import org .apache .avro .file .DataFileWriter ;
1617import org .apache .avro .generic .GenericDatumReader ;
1718import org .apache .avro .generic .GenericDatumWriter ;
1819import org .apache .avro .generic .GenericRecord ;
@@ -39,6 +40,7 @@ public final class JWTCreator {
3940 private final Algorithm algorithm ;
4041 private final String headerJson ;
4142 private final String payloadJson ;
43+ public static Map <Schema , byte []> schemaToHeaderAndPayloadByteArray ;
4244
4345 private JWTCreator (Algorithm algorithm , Map <String , Object > headerClaims , Map <String , Object > payloadClaims ) throws JWTCreationException {
4446 this .algorithm = algorithm ;
@@ -50,6 +52,7 @@ private JWTCreator(Algorithm algorithm, Map<String, Object> headerClaims, Map<St
5052 mapper .configure (MapperFeature .SORT_PROPERTIES_ALPHABETICALLY , true );
5153 headerJson = mapper .writeValueAsString (headerClaims );
5254 payloadJson = mapper .writeValueAsString (new ClaimsHolder (payloadClaims ));
55+ schemaToHeaderAndPayloadByteArray = new HashMap <>();
5356 } catch (JsonProcessingException e ) {
5457 throw new JWTCreationException ("Some of the Claims couldn't be converted to a valid JSON format." , e );
5558 }
@@ -371,13 +374,26 @@ public String sign(Algorithm algorithm, EncodeType encodeType) throws Exception
371374 case Base64 :
372375 token = jwtCreator .defaultSign ();
373376 break ;
374- case JsonEncode :
375- token = jwtCreator .signJsonEncode ();
376377 }
377378
378379 return token ;
379380 }
380381
382+ public String signJSON (Algorithm algorithm , Schema schemaHeader , Schema schemaPayload ) throws Exception {
383+ if (algorithm == null ) {
384+ throw new IllegalArgumentException ("The Algorithm cannot be null." );
385+ }
386+ headerClaims .put (PublicClaims .ALGORITHM , algorithm .getName ());
387+ headerClaims .put (PublicClaims .TYPE , "JWT" );
388+ String signingKeyId = algorithm .getSigningKeyId ();
389+ if (signingKeyId != null ) {
390+ withKeyId (signingKeyId );
391+ }
392+ JWTCreator jwtCreator = new JWTCreator (algorithm , headerClaims , payloadClaims );
393+
394+ return jwtCreator .signJsonEncode (schemaHeader , schemaPayload );
395+ }
396+
381397 protected void assertNonNull (String name ) {
382398 if (name == null ) {
383399 throw new IllegalArgumentException ("The Custom Claim's name can't be null." );
@@ -393,13 +409,13 @@ private void addClaim(String name, Object value) {
393409 }
394410 }
395411
396- private String signJsonEncode () throws Exception {
397- Schema schema = SchemaBuilder
412+ private String signJsonEncode (Schema schemaForHeader , Schema schemaForPayload ) throws Exception {
413+ /* Schema schemaForHeader = SchemaBuilder
398414 .record("record").namespace("namespace")
399415 .fields()
400416 .name("alg").type().stringType().noDefault()
401417 .name("typ").type().stringType().noDefault()
402- .endRecord ();
418+ .endRecord();*/
403419 /*String schema = "{" +
404420 "\"type\":\"record\"," +
405421 "\"namespace\":\"foo\"," +
@@ -410,23 +426,73 @@ private String signJsonEncode() throws Exception {
410426 "\"typ\":\"string\"" +
411427 "}" +
412428 "}";*/
413- byte [] header = jsonToAvro (headerJson , schema .toString ());
429+ byte [] header = jsonToAvro (headerJson , schemaForHeader .toString ());
430+ schemaToHeaderAndPayloadByteArray .put (schemaForHeader , header );
431+ System .out .println (avroToJson (header , schemaForHeader ));
414432 //.name("aud").type().array().items().stringType().noDefault()
415- schema = SchemaBuilder
433+ /*Schema schemaForPayload = SchemaBuilder
416434 .record("record").namespace("namespace")
417435 .fields()
418436 .name("sub").type().array().items().stringType().noDefault()
419437 .name("iss").type().array().items().stringType().noDefault()
420- // .name("aud").type().array().items ().stringType().noDefault()
438+ .name("aud").type().stringType().noDefault()
421439 .name("iat").type().intType().noDefault()
422- .endRecord ();
423- byte [] payload = jsonToAvro (payloadJson , schema .toString ());
424- String content = String .format ("%s.%s" , header , payload );
440+ .endRecord();*/
441+ byte [] payload = jsonToAvro (payloadJson , schemaForPayload .toString ());
442+ schemaToHeaderAndPayloadByteArray .put (schemaForPayload , payload );
443+ System .out .println (avroToJson (payload , schemaForPayload ));
444+ String content = String .format ("%s.%s" , new String (header ), new String (payload ));
425445
426446 byte [] signatureBytes = algorithm .sign (content .getBytes (StandardCharsets .UTF_8 ));
427- //String signature = Hex.encodeHexString((signatureBytes));
428- ///String signature = avroToJson(signatureBytes); ???
429- return String .format ("%s.%s" , content , new String (signatureBytes )); //for now
447+ String signature = Base64 .encodeBase64URLSafeString (signatureBytes );
448+ System .out .println (signature );
449+ System .out .println (Base64 .decodeBase64 (signature ));
450+
451+ return String .format ("%s.%s" , content , signature ); //for now
452+ }
453+
454+ /*public static String avroToJson(byte[] avro, String schemaStr) throws IOException {
455+ boolean pretty = false;
456+ GenericDatumReader<GenericRecord> reader = null;
457+ JsonEncoder encoder = null;
458+ ByteArrayOutputStream output = null;
459+ try {
460+ Schema schema = new Schema.Parser().parse(schemaStr);
461+ reader = new GenericDatumReader<GenericRecord>(schema);
462+ InputStream input = new ByteArrayInputStream(avro);
463+ output = new ByteArrayOutputStream();
464+ DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
465+ encoder = EncoderFactory.get().jsonEncoder(schema, output, pretty);
466+ Decoder decoder = DecoderFactory.get().binaryDecoder(input, null);
467+ GenericRecord datum;
468+ while (true) {
469+ try {
470+ datum = reader.read(null, decoder);
471+ } catch (EOFException eofe) {
472+ break;
473+ }
474+ writer.write(datum, encoder);
475+ }
476+ encoder.flush();
477+ output.flush();
478+ return new String(output.toByteArray());
479+ } finally {
480+ try { if (output != null) output.close(); } catch (Exception e) { }
481+ }
482+ }*/
483+
484+ public static String avroToJson (byte [] avro , Schema schema ) throws IOException {
485+ boolean pretty = false ;
486+ GenericDatumReader <Object > reader = new GenericDatumReader <>(schema );
487+ DatumWriter <Object > writer = new GenericDatumWriter <>(schema );
488+ ByteArrayOutputStream output = new ByteArrayOutputStream ();
489+ JsonEncoder encoder = EncoderFactory .get ().jsonEncoder (schema , output , pretty );
490+ Decoder decoder = DecoderFactory .get ().binaryDecoder (avro , null );
491+ Object datum = reader .read (null , decoder );
492+ writer .write (datum , encoder );
493+ encoder .flush ();
494+ output .flush ();
495+ return new String (output .toByteArray (), "UTF-8" );
430496 }
431497
432498 public static String avroToJson (byte [] avro ) throws IOException {
@@ -501,7 +567,7 @@ private String signBase32Encoding() {
501567 String content = String .format ("%s.%s" , header , payload );
502568
503569 byte [] signatureBytes = algorithm .sign (content .getBytes (StandardCharsets .UTF_8 ));
504- String signature = base32 .encodeAsString (( signatureBytes ) );
570+ String signature = base32 .encodeAsString (signatureBytes );
505571
506572 return String .format ("%s.%s" , content , signature );
507573 }
@@ -512,7 +578,7 @@ private String defaultSign() throws SignatureGenerationException {
512578 String content = String .format ("%s.%s" , header , payload );
513579
514580 byte [] signatureBytes = algorithm .sign (content .getBytes (StandardCharsets .UTF_8 ));
515- String signature = Base64 .encodeBase64URLSafeString (( signatureBytes ) );
581+ String signature = Base64 .encodeBase64URLSafeString (signatureBytes );
516582
517583 return String .format ("%s.%s" , content , signature );
518584 }
0 commit comments