# HTTPS Client/Server Example - Grizzly

This example demonstrates how to develop RESTful HTTPS Server using Grizzly and how to implement HTTPS Client using Jersey with server authentication.

## Contents

### Server side

This example consists of just one resource - RootResource, which is basically copy of HelloWorld Resource from corresponding sample with little improvement.

Other classes are used to start Grizzly embedded server and set up its authentication and authorization mechanism and keystore and truststore.

### Client side

Client side is implemented as a test case, see class com.sun.jersey.samples.https_grizzly.MainTest, and its method `testSSLWithAuth` (others are just tests for invalid authorization). First thing you have to do if you want to communicate with service via https is set up SSLContext which is basically providing keystore and truststore. Keystore is used for storing own keys and truststore is used for storing certificates to which you have decided to trust. For more informations see [1].

To set SSLContext on Jersey client you have to create instance of com.sun.jersey.client.urlconnection.HTTPSProperties and set it as a property to the client instance:

        HTTPSProperties prop = new HTTPSProperties(null, context);

        DefaultClientConfig dcc = new DefaultClientConfig();
        dcc.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, prop);

        Client c = Client.create(dcc);

### Certificates setup

These steps are not required to run this example. Pregenerated keystore and truststore files are already present. Password used was "asdfgh".

We needed set up few things to get this example working:

- generate client and server keys
- generate client and server certificates
- import certificates to corresponding truststores

Client certificate is needed too because we're going to use server-side certificate authentication as well (yes, after this HTTP Basic authentication seems to be kind of redundant but there are some usecases where you might want to use them both).

Generate client key and store it into keystore:

    keytool -genkey -keystore ./keystore_client -alias clientKey -dname "CN=Client, OU=Jersey, O=Oracle, L=Prague, ST=Czech Republic, C=CZ"

Generate client certificate (this will generate self-signed certificate; if you have certification authority and want generate certificate request, use keytool -certreq):

    keytool -export -alias clientKey -rfc -keystore ./keystore_client > ./client.cert

Import client certificate to servers truststore:

    keytool -import -alias clientCert -file ./client.cert -keystore ./truststore_server

These steps are similar for server side:

    keytool -genkey -keystore ./keystore_server -alias serverKey -dname "CN=localhost, OU=Jersey, O=Oracle, L=Prague, ST=Czech Republic, C=CZ"
    keytool -export -alias serverKey -rfc -keystore ./keystore_server > ./server.cert
    keytool -import -alias serverCert -file ./server.cert -keystore ./truststore_client

## Running the Example

Run the example as follows:

test

> `mvn test`

run

> `mvn compile exec:java`

From a web browser, visit:
This won't work! *

> `https://localhost:4463/`

[*] Your web browser needs have and use generated client keys. Or you have to disable server side client authentication - set NeedClientAuth to false: new SSLEngineConfigurator(sslContext).setClientMode(false).setNeedClientAuth(false) in Server.java. Then ignore any security warning (self-signed certificates aren't trusted in general) and login with username "user" and password "password". Text "JERSEY HTTPS EXAMPLE" should appear.

Mozila Firefox and Internet Explorer don't allow users to display any content provided on behalf of any self-signed certificate so you have to use some other browser which allows this (for example Safari or Opera).

## References

[1] http://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html