Table of contents
Other clients:
Overview
Freja eID Signature services allow relying parties to securely deliver messages to a user, as well as to prompt Freja eID end users to digitally sign data and documents. The key difference between the Authentication services and the Signature services in terms of flow is that, whereas a user can only have one authentication transaction active at any given time and the duration of authentication transactions is limited to two minutes, multiple signatures can be pending for a user's approval and each individual signature transaction can be open for up to 30 days.
For more detailed information about the Signature services, please refer to Freja eID Relying Party Developers' Documentation.
Initialising SignClient
Build an instance of SignClientApi interface as shown in the examples below. Note that the SignClient has its own Builder class, which is used for instantiation of SignClient objects. This way of creating objects requires passing mandatory parameters in the Builder constructor, while the rest of parameters can be passed through the Builder setter functions.
SSL initialisation
There are two ways of establishing the SSL connection with the server and passing the client key pair and the server certificate.
The following example shows how to pass the client key pair and the server certificate using a keystore object.
HTTPS proxy settings
In case that you're using a HTTPS proxy server to reach services and sites outside of your company network you'll have to provide details about the proxy server host and port to the library.
The library uses a standard Java mechanism for configuring HTTPS proxy which assumes setting system properties https.proxyHost and https.proxyPort to provide the hostname and port of the proxy server (optionally, a system property http.nonProxyHosts can be set if you need to provide a list of hosts for which you don't need a proxy).
More about configuring HTTPS proxy via system variables in Java you can read here: https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html (section 2.2 and 2.1).
/* * In order to establish SSL with server, client should provide path of keystore file * where key pair with appropriate SSL certificate is stored. * Change the path(C:\\keystore.ks in the example) to match your setup. */ String clientKeystorePath = "C:\\keystore.ks"; /* * The password of client keystore. Change the password (123123 in the example) to match your setup. */ String clientKeystorePass = "123123"; /* * Initialize SignClient with keystore parameters. */ SignClientApi signClient = new SignClient.Builder(clientKeystorePath, clientKeystorePass).build();
The next example is more advanced way of SSL initialisation, where the key pair and the server certificate are passed using the SSLContext object.
/* * In order to establish SSL with server, client should provide SSLContext object from javax.net.ssl * package, created using keystore file where key pair with appropriate SSL certificate is stored. */ /* * Creating KeyStore object * Client should provide path of keystore file, where the key pair * with appropriate SSL certificate is stored. * Change the path(C:\\keystore.ks in the example) to match your setup. */ String clientKeystorePath = "C:\\keystore.ks"; /* * The password of client keystore. Change the password (123123 in the example) to match your setup. */ String clientKeystorePass = "123123"; try (InputStream keyStoreStream = new FileInputStream(clientKeystorePath )) { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(keyStoreStream, clientKeystorePass.toCharArray()); } catch (Exception ex) { Log.error(ex,"failed to create keystore object!"); } KeyManagerFactory keyManagerFactory = KeyManagerFactory .getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, keystorePass.toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null); /* * Initialize SignClient with SSLContext object. */ SignClientApi signClient = new SignClient.Builder(sslContext).build();
Test environment
During the implementation and the testing period, you can use the Freja eID demo environment. In that case, when initialising SignClient, you need to pass the testMode parameter, set to true, like in the example below.
/* * Boolean value which indicates that RP API Client is in test mode. If this value is not set * or is set to false, RP API Client is using Freja eID production environment. Otherwise, * it is using test environment, which is suitable for testing client applications. */ SignClientApi signClient = new SignClient.Builder(sslContext) .testMode(true) .build();
Connection and read timeout configuration
Connection and read timeout can be configured through Builder setter functions. If no other value is specified, by default 20000 ms (2 minutes) will be set.
/* * Connection and read timeout in milliseconds on client side. Connection timeout is time to establish * the connection with remote host. * Read timeout is time waiting for data after the connection was established * (maximum time of inactivity between two data packages). * If value is not specified, it will be 20000 ms by default. */ int connectionTimeoutInMilliseconds = 15000; int readTimeoutInMilliseconds = 15000; SignClientApi signClient = new SignClient.Builder(sslContext) .connectionTimeout(connectionTimeoutInMilliseconds) .readTimout(readTimeoutInMilliseconds ) .build();
Calling a service
This section describes how to make calls to the Freja eID Signature service API and process the response.
Initiate sign
This method is used by a relying party to initiate a signing request. As opposed to authentication requests, multiple signature requests may be active at any given time, from the same or different relying parties.
Signatures can be created both in online contexts, where the access to the relying party's service or application is initiated by the end user, as in offline contexts, where the signature request is initiated by the relying party's service in its own right. Signature transactions, therefore, have configurable longevity — from the point of initiation, the user has between two minutes and 30 days to confirm the signature request.
If the signature type has been set to SIMPLE then the dataToSignType must be SIMPLE_UTF8_TEXT. If the signature type has been set to EXTENDED, then the dataToSignType must be EXTENDED_UTF8_TEXT, in addition dataToSignBinaryData must be provided as well.
/* * Parameter userInfoType describes the type of user information * supplied to identify the end user. * Supported types in this version: EMAIL, PHONE and SSN. * See example below; */ UserInfoType userInfoType = UserInfoType.EMAIL; /* * Change the userInfo value (joe.black@verisec.com in the example) to match your setup. * If user info type is EMAIL, PHONE or Swedish SSN, it's interpreted as their string value. * e.g. in case of UserInfoType.PHONE, userInfo = "+467123456789", * in case of UserInfoType.EMAIL, userInfo = "example@test.com", * in case of UserInfoType.INFERRED userInfo must be explicitly set to "N/A", * in case of UserInfoType.SSN for Swedish SSN, userInfo = "198511170040". * In case of UserInfoType.SSN for non-Swedish SSN, information about the user shall be packed in a SsnUserInfo object that contains the country code and SSN itself like * SsnUserInfo ssnUserInfo = new SsnUserInfo("NO", "31019411411") */ String userInfo = "joe.black@verisec.com"; /* * Parameter restrict, optional, describes a value that restricts the sign action only to the * Freja eID mobile application started with the same parameter. * This can be used in situations where the relying party service * is accessed through a browser or app on the same device as the Freja eID app. * By passing the same restrict value to the initSignRequest as to the start of * the mobile application, the relying party application can target the usage of * the Freja eID on the same device. * Currently, parameter restrict is not supported. */ String restrict = null; /* * Parameter minRegistrationLevel, optional, describes * minimum required registration level of a user in order to * approve/decline signing transaction. If not present, default level will be PLUS. */ RegistrationState minRegistrationLevel = RegistrationState.EXTENDED; /* * Parameter title, optional, describes the title to display in the transaction * if presented to the user on the mobile device. The title will be presented regardless of the * confidentiality setting. If not present, a system default text will be presented: * String title = "Confirm action". */ String title = "Transaction title"; /* * Parameters pushNotificationTitle and pushNotificationText, optional, describe * the title and the text of the notification sent to the mobile * device to alert the user of a signature request. * If not present, a system default title and text will be presented: * String pushNotificationTitle = "Sign", * String pushNotificationText = "You have an action to sign in Freja eID". */ String pushNotificationTitle = "Sign notification title"; String pushNotificationText = "Sign notification text"; /* * Parameter confidential, optional, determines whether the user * will be required to enter their Freja eID PIN * or, if enabled, use the handheld device's biometric authentication method * before being allowed to view the content of the transaction. * If not present, defaults to false. * Currently, parameter confidential is not supported. */ Boolean confidential = false; /* * Parameter expiry, optional, describes the time until which the relying party * is ready to wait for the user to confirm the signature request. * Expressed in milliseconds since January 1, 1970, 00:00 UTC. * Min value is current time +2 minutes, max value is current * time +30 days. If not present, defaults to current time +2 minutes. */ Long expiry = Instant.now().plus(3,ChronoUnit.MINUTES).getEpochSecond() * 1000; /* * Parameter dataToSignType describes the type of data to be signed. * Currently, SIMPLE_UTF8_TEXT and EXTENDED_UTF8_TEXT are supported. * Below is an example of SIMPLE_UTF8_TEXT. */ DataToSignType dataToSignType = DataToSignType.SIMPLE_UTF8_TEXT; /* * Parameter dataToSign is the text that will be shown in the mobile application and * signed by the end user. */ String dataToSignText = "Would you like to transfer 1000 EUR from account A to account B?”; /* * If the Parameter dataToSign is type EXTENDED_UTF8_TEXT then the following must be provided. * This is data that is included in the signature but is not visible to the user. */ byte[] dataToSignBinaryData = "Binary data, not presented to the user.".getBytes(StandardCharsets.UTF_8); /* * Parameter signatureType describes the type of signature that is requested. * Currently supported are SIMPLE and EXTENDED signature types. * Below is an example of a SIMPLE signature. */ SignatureType signatureType = SignatureType.SIMPLE; /* * Parameter attributesToReturn is used to request additional information about the user. * Interpreted as a set of attributes that represent that extra information is required. * The requested information is returned when fetching authentication results. */ Set<AttributeToReturn> attributes = new HashSet(); attributes.add(AttributeToReturn.BASIC_USER_INFO_ATTR); attributes.add(AttributeToReturn.EMAIL_ADDRESS_ATTR); attributes.add(AttributeToReturn.DATE_OF_BIRTH_ATTR); attributes.add(AttributeToReturn.RELYING_PARTY_USER_ID_ATTR); attributes.add(AttributeToReturn.SSN_ATTR); /* * In case of Initiate sign method, response type is InitiateSignResponse. * The only data in this response is the signature transaction reference. */ InitiateSignResponse initiateSignResponse = signClientApi.initSign( userInfoType, userInfo, restrict, title, minRegistrationLevel, pushNotificationTitle, pushNotificationText, confidential, expiry, dataToSignType, dataToSignText, dataToSignBinaryData, signatureType, attributes); String transactionReference = initiateSignResponse.getSignRef();
Get one signature result
This method is used to fetch a single result for a specified signature transaction reference (signRef returned from a call to Initiate sign method).
/* * A reference unique to the transaction that can be used to query the result of a transaction. */ String signRef ="reference"; /* * In case of getOneSignResult method, response type is GetOneSignResultResponse. * Response contains: signature transaction reference of the signing request, * the status of the action and details (can be used for extra validation of response). * Response contains additional attributes (basicUserInfo - user's * name and surname, emailAddress - user's email address, dateOfBirth - user's date of birth, relyingPartyUserId, customIdentifier, ssn - country and ssn). */ GetOneSignResultResponse response = signClient.getOneSignResult(signRef); String receivedSignRef = response.getSignRef(); ActionStatus status = response.getStatus(); String details = response.getDetails(); RequestedAttributes requestedAttributes = response.getRequestedAttributes(); BasicUserInfo basicUserInfo = requestedAttributes.getBasicUserInfo(); String emailAddress = requestedAttributes.getEmailAddress(); SsnUserInfo ssn = requestedAttributes.getSsn(); String relyingPartyUserId = requestedAttributes.getRelyingPartyUserId(); String dateOfBirth = requestedAttributes.getDateOfBirth();
Get signature results
This method is used to fetch the results of multiple outstanding signature requests.
/* * Response type is GetSignResultsResponse. * The response will contain a complete list of signature requests * successfully initiated by the relying party. * The time period during which a specific signature reference is available for checking will depend on * the longevity of the signature operation (see the expiry parameter in the Initiate sign method) * and is calculated as expiry time plus 3 days. */ GetSignResultsResponse response = signClient.getSignResults(); /* * As final result of getSignResults method, a list of transaction responses is received. */ List<GetOneSignResultResponse> responses = response.getSignatureResults();
Cancel signature
This method is used to cancel an initiated signature request.
/* * A reference unique to the transaction that can be used to query the result of the transaction. */ String authRef ="reference"; /* * Response type is EmptyFrejaResponse. * The response is empty. */ List<EmptyFrejaResponse> response = signClient.cancelSign();
Logging
Freja eID Relying Party API Client provides a logger you can include in your application. Details can be found in the Logging section.