Skip to content

Latest commit

 

History

History
103 lines (83 loc) · 3.53 KB

File metadata and controls

103 lines (83 loc) · 3.53 KB

SCRAM Client API

Javadocs

For general description, please refer to the main README.md.

How to use the client API

  1. Add Maven (or equivalent) dependencies :
<dependency>
    <groupId>com.ongres.scram</groupId>
    <artifactId>client</artifactId>
    <version>VERSION</version>
</dependency>
  1. Get a ScramClient. A ScramClient can be configured with several parameters, and matches a given server. From the client, several ScramSessions can be created, for potentially different users. Under certain conditions (read Javadoc) it is thread safe.

A simple example could be:

ScramClient scramClient = ScramClient
    .channelBinding(ChannelBinding.NO)
    .stringPreparation(NO_PREPARATION)
    .serverMechanisms("SCRAM-SHA-1")
    .setup();

More configuration methods and options are available, as shown below:

ScramClient scramClient = ScramClient
    .channelBinding(ChannelBinding.YES)
    .stringPreparation(NO_PREPARATION)
    .serverMechanisms("SCRAM-SHA-1", "SCRAM-SHA-1-PLUS", "SCRAM-SHA-256", "SCRAM-SHA-256-PLUS")
    .nonceSupplier(() -> generateNonce())
    .secureRandomAlgorithmProvider("algorithm", "provider")
    .setup();
  1. For each authentication round and/or user, create a ScramSession and get the client-first-message:
ScramSession scramSession = scramClient.scramSession("user");
scramSession.clientFirstMessage()
  1. Receive the server-first-message:
ScramSession.ServerFirstProcessor serverFirst = scramSession.receiveServerFirstMessage(message);
// Read the salt and iterations:
serverFirst.getSalt()
serverFirst.getIteration()
  1. Generate the client-last-message:
ScramSession.ClientFinalProcessor clientFinal = serverFirst.finalMessagesHandler("password");
clientFinal.clientFinalMessage()
  1. Receive the server-last-message, check if is valid or error, etc:
ScramSession.ServerFinalProcessor serverFinal = clientFinal.receiveServerFinalMessage(message);
// Methods to check if it is error, get error, verify signature
serverFinal.isError()
serverFinal.getErrorMessage()
serverFinal.verifyServerSignature()

Example

The following example runs a full SCRAM session, using the RFC's data as an example.

ScramClient scramClient = ScramClient
        .channelBinding(ScramClient.ChannelBinding.NO)
        .stringPreparation(StringPreparations.NO_PREPARATION)
        .selectMechanismBasedOnServerAdvertised("SCRAM-SHA-1")
        .nonceSupplier(() -> "fyko+d2lbbFgONRv9qkxdawL")
        .setup();

ScramSession scramSession = scramClient.scramSession("user");
System.out.println(scramSession.clientFirstMessage());

ScramSession.ServerFirstProcessor serverFirstProcessor = scramSession.receiveServerFirstMessage(
        "r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096"
);
System.out.println("Salt: " + serverFirstProcessor.getSalt() + ", i: " + serverFirstProcessor.getIteration());

ScramSession.ClientFinalProcessor clientFinalProcessor
        = serverFirstProcessor.clientFinalProcessor("pencil");
System.out.println(clientFinalProcessor.clientFinalMessage());

ScramSession.ServerFinalProcessor serverFinalProcessor
        = clientFinalProcessor.receiveServerFinalMessage("v=rmF9pqV8S7suAoZWja4dJRkFsKQ=");
if(serverFinalProcessor.isError()) {
        // throw authentication exception
}

System.out.println(serverFinalProcessor.verifyServerSignature());