Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Here is an example of a JSON Book representation being HS256 signed and converted into  Compact JWS and POSTed to the target service:

No Format
Address: https://localhost:9001/jwsjwkhmac/bookstore/books
Http-Method: POST
Content-Type: application/jose
Payload: 
eyJhbGciOiJIUzI1NiIsImN0eSI6Impzb24ifQ.
eyJCb29rIjp7ImlkIjoxMjMsIm5hbWUiOiJib29rIn19.
hg1T41ESuX6JvRR--huTA3HnbrsdIZSwkxQdyWj9j6c

May 24, 2016 10:53:32 AM org.apache.cxf.rs.security.jose.common.JoseUtils traceHeaders
INFO: JWS Headers: 
{"alg":"HS256",
 "cty":"json"}

...

You can see 3 JWS parts (put on separate lines for the better readibility) separated by dots. The 1st part is Base64Url encoded protected headers, next one - Base64Url encoded Book JSON payload, finally - the signature.

Note that the protected headers can be traced by enabling a "jose.debug" contextual property: once can see the signature algorithm is "HS256" and the content type of the signed payload is "json" which is a shorcut for a content type "application/json" where "application" is omitted.

The following client code can be used to set the client JOSE JWS Compact interceptors:

Code Block
languagejava
titleClient JWS SetUp
    	public void testJwsJwkBookHMac() throws Exception {
        String address = "https://localhost:" + PORT + "/jwsjwkhmac";
        BookStore bs = createJwsBookStore(address);
        Book book = bs.echoBook(new Book("book", 123L));
        assertEquals("book", book.getName());
        assertEquals(123L, book.getId());
    }
    private BookStore createJwsBookStore(String address, 
                                         List<?> mbProviders) throws Exception {
        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
        bean.setServiceClass(BookStore.class);
        bean.setAddress(address);
        List<Object> providers = new LinkedList<Object>();
        // JWS Compact Out
        JwsWriterInterceptor jwsWriter = new JwsWriterInterceptor();
        // enable streaming 
        jwsWriter.setUseJwsOutputStream(true);
        providers.add(jwsWriter);
        // JWS Compact In
        providers.add(new JwsClientResponseFilter());
        // Book to/from JSON
        providers.add(new JacksonJsonProvider());
        bean.setProviders(providers);
        // point to the JWS security properties
        bean.getProperties(true).put("rs.security.signature.properties", 
            "org/apache/cxf/systest/jaxrs/security/secret.jwk.properties");
        // enable the tracing of JWS headers
        bean.getProperties(true).put("jose.debug", true);
        
        return bean.create(BookStore.class);
    }

...

JwsJsonClientResponseFilter and JwsJsonContainerRequestFilter process the incoming client or server Compact JWS sequences.

Here is an example of a JSON Book representation being signed and plain text "book" being HS256-signed, converted into JWS JSON and POSTed to the target service:

No Format
Http-Method: POST
Content-Type: application/jose+json
Payload: 
{
  "payload" : "eyJCb29rIjp7ImlkIjoxMjMsIm5hbWUiOiJib29rIn19Ym9vaw",
  "signatures":
   [
     {
       "protected" : "eyJhbGciOiJIUzI1NiIsImN0eSI6Impzb24ifQ",
       "signature" : "hg1T41ESuX6JvRR--huTA3HnbrsdIZSwkxQdyWj9j6cdRUibW7F6LyXuOc78DHubUIave0QUSvte5iv6xoJaL4"
     }
   ]
}

Note the Base64Url encoded payload goes first, followed by the 'signatures' array, with each element containing the protected headers and the actual signature specific to a given signature key.

Enabling the clear JWS payload option wilkl produce:

No Format
{
 "payload" : "{"Book":{"id":123,"name":"book"}}",  
 "signatures": 
   [
      {
       "protected" : "eyJhbGciOiJIUzI1NiIsImN0eSI6Impzb24iLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQeyJhbGciOiJIUzI1NiIsImN0eSI6InRleHQvcGxhaW4iLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ",
       "signature" : "AwHX5IVrGLXQicma-aaRAyLuHQcKc65fE3uclfM7O2IVO3NsQeTGrFiMeLf_LonO8TKTsMSqnqmjnK40PwQ88"
      }
   ]
}

The client code and server configuration is nearly identical to a code/configuration needed to set up JWS Compact filters as shown above, simply replace JwsWriterInterceptor/JwsClientResponseFilter with JwsJsonWriterInterceptor/JwsJsonClientResponseFilter in the client code, and JwsContainerRequestFilter/JwsContainerResponseFilter with JwsJsonContainerRequestFilter/JwsJsonContainerResponseFilter

...

JweClientResponseFilter and JweContainerRequestFilter process the incoming client or server Compact JWE sequences.

 

JweJsonWriterInterceptor creates JWE JSON sequences on the client or server out directions. 

JweJsonClientResponseFilter and JweContainerRequestFilter process the incoming client or server JWE JSON sequences.

Here is an example of a plain text "book" being encrypted with the A128KW key and A128GCM content encryption (see JWE section above), converted into Compact JWE and POSTed to the target service:

No Format
Address: https://localhost:9001/jwejwkaeswrap/bookstore/books
Http-Method: POST
Content-Type: application/jose
Payload: 
eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwiY3R5IjoidGV4dC9wbGFpbiJ9.
SQul1USvHmADDLpBvY2Dnqk5GpoowOkJ.
cFuCSzRsl6GZuvHL.
akVT5g.
i8rpTk-v0b1IyE1sVT1IOA

org.apache.cxf.rs.security.jose.common.JoseUtils traceHeaders
INFO: JWE Headers: 
{"alg":"A128KW",
 "enc":"A128GCM",
 "cty":"text/plain"}

You can see 5 JWE parts (put on separate lines for the better readibility) separated by dots. The 1st part is Base64Url encoded protected headers, next one - Base64Url encoded content encryption key, next one - Base64Url encoded IV, next one - Base64Url encoded ciphertext, finally - the authentication tag.

Note that the protected headers can be traced by enabling a "jose.debug" contextual property: once can see the key encryption algorithm is "A128KW", content encryption algorithm is "A128GCM" and the content type of the encrypted payload is "text/plain".

The following client code can be used to set the client JWE Compact interceptors:

Code Block
languagejava
titleClient JWE SetUp
    public void testJweJwkAesWrap() throws Exception {
        String address = "https://localhost:" + PORT + "/jwejwkaeswrap";
        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
        bean.setServiceClass(BookStore.class);
        bean.setAddress(address);
        List<Object> providers = new LinkedList<Object>();
        JweWriterInterceptor jweWriter = new JweWriterInterceptor();
        jweWriter.setUseJweOutputStream(true);
        providers.add(jweWriter);
        providers.add(new JweClientResponseFilter());
        bean.setProviders(providers);
        bean.getProperties(true).put("rs.security.encryption.properties",
                                     "org/apache/cxf/systest/jaxrs/security/secret.jwk.properties");
        bean.getProperties(true).put("jose.debug", true);
        BookStore bs = bean.create(BookStore.class);
        String text = bs.echoText("book");
        assertEquals("book", text);
    }

The above code shows a client proxy code but WebClient can be created instead. The server is configured here. The client can be configured in Spring/Blueprint too.

JweJsonWriterInterceptor creates JWE JSON sequences on the client or server out directions. 

JweJsonClientResponseFilter and JweContainerRequestFilter process the incoming client or server JWE JSON sequences.

Here is the same example for encrypting "book" but with JWS JSON interceptors:

No Format
Address: https://localhost:9001/jwejsonhmac/bookstore/books
Http-Method: POST
Content-Type: application/jose+json
Payload: 
{
  "protected" : "eyJlbmMiOiJBMTI4R0NNIiwiY3R5IjoidGV4dC9wbGFpbiIsImFsZyI6IkExMjhLVyJ9",
  "recipients":
   [
     {
       "encrypted_key": "iq1vJBpOHKRkMDoY2GTakWE6M_uPGVsh"
     }
   ],
   "iv":"SUpOEf-7Q1tT0JV_",
   "ciphertext":"alKm_g",
   "tag":"DkW2pZCd7lhR0KqIGQ69-A"
}

Note the Base64Url encoded protected headers go first, followed by the 'recipients' array, with each element containing the encrypted content encryption key which can be decrypted by the recipient private key, with the array of recipients followed by the IV, ciphertext and authentication tag Base64Url sequences. 

Linking JWT authentications to JWS or JWE content

...