ee.sk.smartid.SmartIdClient Maven / Gradle / Ivy
Show all versions of smart-id-java-client Show documentation
package ee.sk.smartid;
/*-
* #%L
* Smart ID sample Java client
* %%
* Copyright (C) 2018 SK ID Solutions AS
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* #L%
*/
import ee.sk.smartid.rest.SessionStatusPoller;
import ee.sk.smartid.rest.SmartIdConnector;
import ee.sk.smartid.rest.SmartIdRestConnector;
import org.glassfish.jersey.client.ClientConfig;
import java.util.concurrent.TimeUnit;
/**
* Class that can be used to configure and get different types of request builders
*
* Basic example of authentication:
*
* // Client setup. Note that these values are demo environment specific.
* SmartIdClient client = new SmartIdClient();
* client.setRelyingPartyUUID("00000000-0000-0000-0000-000000000000");
* client.setRelyingPartyName("DEMO");
* client.setHostUrl("https://sid.demo.sk.ee/smart-id-rp/v1/");
*
* NationalIdentity identity = new NationalIdentity("EE", "31111111111");
*
* // For security reasons a new hash value must be created for each new authentication request
* AuthenticationHash authenticationHash = AuthenticationHash.generateRandomHash();
*
* // verification code should be displayed by the web service, so the person signing through the Smart-ID mobile app can verify
* // if the verification code displayed on the phone matches with the one shown on the web page.
* String verificationCode = authenticationHash.calculateVerificationCode());
*
* SmartIdAuthenticationResponse authenticationResponse = client
* .createAuthentication()
* .withNationalIdentity(identity)
* .withAuthenticationHash(authenticationHash)
* .authenticate();
*
* // The authenticationResponse should also be validated with
* // AuthenticationResponseValidator's validate(SmartIdAuthenticationResponse) method afterwards.
*
*
* Basic example of choosing a (device) certificate and then creating signature with it:
*
* // Client setup. Note that these values are demo environment specific.
* SmartIdClient client = new SmartIdClient();
* client.setRelyingPartyUUID("00000000-0000-0000-0000-000000000000");
* client.setRelyingPartyName("DEMO");
* client.setHostUrl("https://sid.demo.sk.ee/smart-id-rp/v1/");
*
* NationalIdentity identity = new NationalIdentity("EE", "31111111111");
*
* SmartIdCertificate certificateResponse = client
* .getCert()
* .withNationalIdentity(identity)
* .fetch();
*
* // get the document number for creating signature
* String documentNumber = certificateResponse.getDocumentNumber();
*
* SignableHash hashToSign = new SignableHash();
* hashToSign.setHashType(HashType.SHA256);
* hashToSign.setHashInBase64("0nbgC2fVdLVQFZJdBbmG7oPoElpCYsQMtrY0c0wKYRg=");;
*
* // to display the verificationCode on the web page
* String verificationCode = dataToSign.calculateVerificationCode();
* SmartIdSignature signature = client
* .createSignature()
* .withDocumentNumber(documentNumber)
* .withSignableHash(hashToSign)
* .withCertificateLevel("QUALIFIED")
* .sign();
* byte[] signature = signature.getValue();
*
* @see https://github.com/SK-EID/smart-id-java-client/wiki/Examples-of-using-it
*/
public class SmartIdClient {
private String relyingPartyUUID;
private String relyingPartyName;
private String hostUrl;
private ClientConfig networkConnectionConfig;
private TimeUnit pollingSleepTimeUnit = TimeUnit.SECONDS;
private long pollingSleepTimeout = 1L;
private TimeUnit sessionStatusResponseSocketOpenTimeUnit;
private long sessionStatusResponseSocketOpenTimeValue;
private SmartIdConnector connector;
/**
* Gets an instance of the certificate request builder
*
* @return certificate request builder instance
*/
public CertificateRequestBuilder getCertificate() {
SessionStatusPoller sessionStatusPoller = createSessionStatusPoller(getSmartIdConnector());
CertificateRequestBuilder builder = new CertificateRequestBuilder(getSmartIdConnector(), sessionStatusPoller);
populateBuilderFields(builder);
return builder;
}
/**
* Gets an instance of the signature request builder
*
* @return signature request builder instance
*/
public SignatureRequestBuilder createSignature() {
SessionStatusPoller sessionStatusPoller = createSessionStatusPoller(getSmartIdConnector());
SignatureRequestBuilder builder = new SignatureRequestBuilder(getSmartIdConnector(), sessionStatusPoller);
populateBuilderFields(builder);
return builder;
}
/**
* Gets an instance of the authentication request builder
*
* @return authentication request builder instance
*/
public AuthenticationRequestBuilder createAuthentication() {
SessionStatusPoller sessionStatusPoller = createSessionStatusPoller(getSmartIdConnector());
AuthenticationRequestBuilder builder = new AuthenticationRequestBuilder(getSmartIdConnector(), sessionStatusPoller);
populateBuilderFields(builder);
return builder;
}
/**
* Sets the UUID of the relying party
*
* Can be set also on the builder level,
* but in that case it has to be set explicitly
* every time when building a new request.
*
* @param relyingPartyUUID UUID of the relying party
*/
public void setRelyingPartyUUID(String relyingPartyUUID) {
this.relyingPartyUUID = relyingPartyUUID;
}
/**
* Gets the UUID of the relying party
*
* @return UUID of the relying party
*/
public String getRelyingPartyUUID() {
return relyingPartyUUID;
}
/**
* Sets the name of the relying party
*
* Can be set also on the builder level,
* but in that case it has to be set
* every time when building a new request.
*
* @param relyingPartyName name of the relying party
*/
public void setRelyingPartyName(String relyingPartyName) {
this.relyingPartyName = relyingPartyName;
}
/**
* Gets the name of the relying party
*
* @return name of the relying party
*/
public String getRelyingPartyName() {
return relyingPartyName;
}
/**
* Sets the base URL of the Smart-ID backend environment
*
* It defines the endpoint which the client communicates to.
*
* @param hostUrl base URL of the Smart-ID backend environment
*/
public void setHostUrl(String hostUrl) {
this.hostUrl = hostUrl;
}
/**
* Sets the network connection configuration
*
* Useful for configuring network connection
* timeouts, proxy settings, request headers etc.
*
* @param networkConnectionConfig Jersey's network connection configuration instance
*/
public void setNetworkConnectionConfig(ClientConfig networkConnectionConfig) {
this.networkConnectionConfig = networkConnectionConfig;
}
/**
* Sets the timeout for each session status poll
*
* Under the hood each operation (authentication, signing, choosing
* certificate) consists of 2 request steps:
*
* 1. Initiation request
*
* 2. Session status request
*
* Session status request is a long poll method, meaning
* the request method might not return until a timeout expires
* set by this parameter.
*
* Caller can tune the request parameters inside the bounds
* set by service operator.
*
* If not provided, a default is used.
*
* @param timeUnit time unit of the {@code timeValue} argument
* @param timeValue time value of each status poll's timeout.
*/
public void setSessionStatusResponseSocketOpenTime(TimeUnit timeUnit, long timeValue) {
sessionStatusResponseSocketOpenTimeUnit = timeUnit;
sessionStatusResponseSocketOpenTimeValue = timeValue;
}
/**
* Sets the timeout/pause between each session status poll
*
* @param unit time unit of the {@code timeout} argument
* @param timeout timeout value in the given {@code unit}
*/
public void setPollingSleepTimeout(TimeUnit unit, long timeout) {
pollingSleepTimeUnit = unit;
pollingSleepTimeout = timeout;
}
private void populateBuilderFields(SmartIdRequestBuilder builder) {
builder.withRelyingPartyUUID(relyingPartyUUID);
builder.withRelyingPartyName(relyingPartyName);
}
private SessionStatusPoller createSessionStatusPoller(SmartIdConnector connector) {
connector.setSessionStatusResponseSocketOpenTime(sessionStatusResponseSocketOpenTimeUnit, sessionStatusResponseSocketOpenTimeValue);
SessionStatusPoller sessionStatusPoller = new SessionStatusPoller(connector);
sessionStatusPoller.setPollingSleepTime(pollingSleepTimeUnit, pollingSleepTimeout);
return sessionStatusPoller;
}
public SmartIdConnector getSmartIdConnector() {
if (null == connector) {
// Fallback to REST connector when not initialised
SmartIdRestConnector connector = new SmartIdRestConnector(hostUrl, networkConnectionConfig);
connector.setSessionStatusResponseSocketOpenTime(sessionStatusResponseSocketOpenTimeUnit, sessionStatusResponseSocketOpenTimeValue);
setSmartIdConnector(new SmartIdRestConnector(hostUrl, networkConnectionConfig));
}
return connector;
}
public void setSmartIdConnector(SmartIdConnector smartIdConnector) {
this.connector = smartIdConnector;
}
}