For general description, please refer to the main README.md.
- Add Maven (or equivalent) dependencies :
<dependency>
<groupId>com.ongres.scram</groupId>
<artifactId>client</artifactId>
<version>VERSION</version>
</dependency>- Get a
ScramClient. AScramClientcan be configured with several parameters, and matches a given server. From the client, severalScramSessions 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();- For each authentication round and/or user, create a
ScramSessionand get the client-first-message:
ScramSession scramSession = scramClient.scramSession("user");
scramSession.clientFirstMessage()- Receive the server-first-message:
ScramSession.ServerFirstProcessor serverFirst = scramSession.receiveServerFirstMessage(message);
// Read the salt and iterations:
serverFirst.getSalt()
serverFirst.getIteration()- Generate the client-last-message:
ScramSession.ClientFinalProcessor clientFinal = serverFirst.finalMessagesHandler("password");
clientFinal.clientFinalMessage()- 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()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());