Authentication Services API Client (DEPRECATED)

 

Overview

Freja eID Authentication services allow Relying Parties to authenticate end users through the use of the Freja eID mobile application. The end user will have previously downloaded the Freja eID mobile application on one or more iOS or Android devices they possess and registered with Freja eID, allowing them to be referred to by Relying Parties through the use of one or more email addresses or phone numbers. A user may have also undergone an extended registration process achieving the status of Freja eID Extended or Plus. To access the Freja eID authentication service, a relying party must use SSL with client authentication, where the client certificate is obtained from Freja eID during the onboarding process

For more detailed information about the Authentication Services, please refer to Freja eID Relying Party Developers' Documentation.



Initialising LoginClient

Build an instance of LoginClientApi interface as shown in the examples below. Note that the LoginClient has its own Builder class, which is used for instantiation of LoginClient 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 to the library.

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 server 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 LoginClient with keystore parameters.
*/
LoginClientApi loginClient = new LoginClient.Builder(clientKeystorePath, clientKeystorePass).build();


The following 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 server SSL certificate is stored.               
*/
/*
* Creating KeyStore object
* Client should provide path of keystore file, where the key pair
* with appropriate server 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, clientKeystorePass.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
/*
* Initialize LoginClient with SSLContext object.
*/
LoginClientApi loginClient = new LoginClient.Builder(sslContext).build();


Using the test environment

During the implementation and the testing period, you can use the Freja eID demo environment. In that case, when initialising LoginClient, you need to pass a 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.
*/
LoginClientApi loginClient = new LoginClient.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 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;
LoginClientApi loginClient = new LoginClient.Builder(sslContext)
								.connectionTimeout(connectionTimeoutInMilliseconds)
								.readTimout(readTimeoutInMilliseconds )
								.build();


Polling timeout configuration

Polling timeout can be configured through Builder setter functions. If no other value is specified, by default 3000 ms will be set.

/*
Parameter pollingTimeout controls the time interval between succeeding HTTP poll requests in the method getFinalLoginResponse.
If no other value is specified for this parameter, it will be 3000 ms by default.
If the value of this parameter is less than 1000 ms or more than 30000 ms, the builder will throw the exception. 
*/
int pollingTimeoutInMilliseconds = 5000;
LoginClientApi loginClient = new LoginClient.Builder(sslContext)
								.pollingTimeout(pollingTimeoutInMilliseconds)
								.build();


Calling a service

This section describes how to make calls to the Freja eID Authentication service API and process the response.

Initiate login

This method is used by a Relying Party to initiate an authentication request. The method is intended for authentication in online contexts, where the access to the Relying Party’s service or application is initiated by the end user. The authentications are, therefore, short-lived – from the point of initiation, the user has maximum two minutes to confirm the authentication through Freja eID mobile application. Only one active authentication may exist for any given end user at any given time. An attempt to concurrently start a second authentication, by the same or different Relying Party, will cancel both initiated authentication requests.

/*
* Describes the type of user information supplied to identify the end user. 
* Supported types in this version: EMAIL, PHONE, SSN and INFERRED.   
* 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";
 
/*
* In case of Initiate authentication method, response type is InitiateLoginResponse. 
* The only data in this response is the authentication transaction reference.
*/
InitiateLoginResponse response = loginClient.initLogin(userInfoType, userInfo);
String transactionReference = response.getAuthRef();

Requesting additional user information

A Relying Party can also ask for additional information about the user. Currently, supported attributes are BASIC_USER_INFO (name and surname), EMAIL_ADDRESS (user's email address), DATE_OF_BIRTH (user's date of birth), RELYING_PARTY_USER_ID (a unique, user-specific value that allows the Relying Party to identify the same user across multiple sessions) and SSN (social security number and country). If this is the case, it is necessary to pass another parameter in Initiate login method - a set of attributes that represents that extra information required.

If the Relying Party is asking for attributes BASIC_USER_INFO, DATE_OF_BIRTH or SSN,  the minRegistrationLevel parameter in the initAuthRequest must be set to EXTENDED or PLUS, otherwise the request will fail.


UserInfoType userInfoType = UserInfoType.SSN;
String ssn = "198511170040";
/*
* Additional information about the user to be returned. Interpreted as a set of attributes 
* that represents that extra information 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);
InitiateLoginResponse response = loginClient.initLogin(userInfoType, ssn, attributes); 

Requesting minimum registration level

When initiating a login, Relying Parties can request the minimum registration level the user should be on in order to complete the authentication. Supported levels are BASIC, EXTENDED and PLUS. This parameter is optional. If it is not forwarded, the default value (BASIC) is used.


UserInfoType userInfoType = UserInfoType.SSN;
String ssn = "198511170040";

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);
/*
* When initiating login, you can request the minimum registration level of the
* user. Supported levels are BASIC, EXTENDED and PLUS.
* If this parameter is not forwarded, default value BASIC is used. 
*/
RegistrationState minimumRegistrationLevel = RegistrationState.PLUS; 
InitiateLoginResponse response = loginClient.initLogin(userInfoType, ssn, minimumRegistrationLevel, attributes);

Get one login result

This method is used by a Relying Party to fetch a single result for a specified authentication reference (authRef returned from a call to Initiate login method). 

/*
* A reference unique to the transaction that can be used to query the result of a transaction.
*/
String authRef ="reference";
 
/*
* In case of getOneAuthenticationResult method, response type is GetOneLoginResultResponse.
* Response contains authentication reference passed during login initiation, status of the action,
* details (can be used for extra validation of response) and, if requested during login initation
* and the action has been approved, 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).
*/
GetOneLoginResultResponse response = loginClient.getOneLoginResult(authRef);
String receivedAuthRef = response.getAuthRef();
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 final login result

This is a blocking method and is used by a Relying Party to fetch a single result with the final status (can be one of: rejected, approved, cancelled or expired) for a specified authentication reference. The method keeps polling until it receives a final status of the login action. If the maximum polling time expires before the action is completed, the method will throw an exception.

/*
* A reference unique to the transaction that can be used to query the result of a transaction.
*/
String authRef ="reference";
 
/*
* A maximum time in seconds to wait for a final status of action
* (to be approved, cancelled, rejected or expired).
*/
int maxWaitingTimeInSec = 120;
/*
* In case of getOneAuthenticationResult method, response type is GetOneLoginResultResponse.
* Response contains authentication reference passed during login initiation, status of the action, 
* details (can be used for extra validation of response) and, if requested during login initation
* and the action has been approved, response contains additional attributes (basicUserInfo - user's 
* name and surname, dateOfBirth - user's date of birth, relyingPartyUserId, customIdentifier, ssn - country and ssn).
* If maxWaitingTimeInSec passes and login action is not completed with one of the final statuses,
* this method will throw RpsClientPollingException.
*/
GetOneLoginResultResponse response = loginClient.getFinalLoginResponse(authRef, maxWaitingTimeInSec);
String receivedAuthRef = response.getAuthRef();
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 login results

This method is used by a Relying Party to fetch the results of multiple outstanding authentications. 

/*
* Response type is GetLoginResultsResponse.
* The response will contain a complete list of authentications, successfully initiated within
* last 10 minutes.
*/ 
GetLoginResultsResponse response = loginClient.getLoginResults();

/*
* As final result of get authentication results method, a list of transaction responses is received.
*/
List<GetOneLoginResultResponse> responses = response.getAuthenticationResults(); 

Cancel login

This method is used to cancel an initiated authentication request.

/*
* A reference unique to the transaction that can be used to query the result of a transaction.
*/
String authRef ="reference";
 
/*
* Response type is EmptyFrejaResponse.
* The response is empty.
*/ 
List<EmptyFrejaResponse> response = loginClient.cancelLogin(authRef);

Logging

Freja eID Relying Party API Client provides a logger you can include in your application. Details can be found in the Logging section.