Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ It is recommended to start using device-link authentication flows from Smart-ID
3. Replace showing verification code with showing device link or QR-code. Recommended to use device link for same device and QR-code for cross-device authentication.
- [Create device link or QR-code](README.md#generating-qr-code-or-device-link) from values in session response and display it to the user. QR-code should be recreated after every second.
4. Querying session status can be done in parallel while displaying device content. Check out [session status poller](README.md#example-of-using-session-status-poller-to-query-final-sessions-status). `ee.sk.smartid.SmartIdClient` provides method `getSessionsStatusPoller()` to get version specific session status poller.
5. When session status state is `COMPLETE` polling will be stopped and [response should be checked](README.md#example-of-validating-the-authentication-sessions-response) with `AuthenticationResponseValidator`. It will validate required fields, certificate and signature value in sessions status, and it will also handler errors.
5. When session status state is `COMPLETE` polling will be stopped and [response should be checked](README.md#example-of-validating-the-authentication-sessions-response) with `DeviceLinkAuthenticationResponseValidator` or `NotificationAuthenticationResponseValidator` (depending on the flow). They will validate required fields, certificate and signature value in sessions status, and they will also handle errors.
6. If everything is ok `AuthenticationIdentity` will be returned. AuthenticationIdentity is same as used for V2.

## Migrating signing
Expand Down
38 changes: 23 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,16 +230,16 @@ Anonymous authentication is a new feature in Smart-ID API v3.1. It allows to aut
RP can learn the user's identity only after the user has authenticated themselves.

```java
// For security reasons a new hash value must be created for each new authentication request
String rpChallenge = RpChallengeGenerator.generate();
// For security reasons a new RP challenge must be created for each new authentication request
RpChallenge rpChallenge = RpChallengeGenerator.generate();
// Store generated rpChallenge only on backend side. Do not expose it to the client side.
// Used for validating authentication sessions status OK response

// Set up builder
DeviceLinkAuthenticationSessionRequestBuilder builder = smartIdClient
.createDeviceLinkAuthentication()
// to use anonymous authentication, do not set semantics identifier or document number
.withRpChallenge(rpChallenge)
.withRpChallenge(rpChallenge.toBase64EncodedValue())
.withInteractions(Collections.singletonList(
DeviceLinkInteraction.displayTextAndPin("Logging into <app-name>") // Display text should be concise and specific.
));
Expand Down Expand Up @@ -794,15 +794,16 @@ if ("RUNNING".equalsIgnoreCase(sessionStatus.getState())) {
### Validating session status response

It's important to validate the session status response to ensure that the returned signature or authentication result is valid.
For validating authentication session status response, use the `AuthenticationResponseValidator`.
For validating authentication session status response, use `DeviceLinkAuthenticationResponseValidator` for device link flows
and `NotificationAuthenticationResponseValidator` for notification-based flows.
For validating signature session status response, use the `SignatureResponseValidator`.
NB! Integrators must validate signature value against expected signature value.

#### Set up CertificateValidator

CertificateValidator will check if the certificate is not expired and is trusted
by constructing certificate chain with trust anchors and intermediate CA certificates provided in the TrustedCACertStore.
Will be used by AuthenticationResponseValidator and SignatureResponseValidator.
Will be used by DeviceLinkAuthenticationResponseValidator, NotificationAuthenticationResponseValidator, CertificateChoiceResponseValidator and SignatureResponseValidator.

```java
// Set up TrustedCACertStore
Expand Down Expand Up @@ -837,11 +838,12 @@ CertificateValidator certificateValidator = new CertificateValidatorImpl(trusted
DeviceLinkAuthenticationResponseValidator depends on CertificateValidator. Checkout [setting up CertificateValidator](#set-up-certificatevalidator)

```java
// Set up AuthenticationResponseValidator with the CertificateValidator
DeviceLinkAuthenticationResponseValidator deviceLinkAuthenticationResponseValidator = new AuthenticationResponseValidator(certificateValidator);
// Set up DeviceLinkAuthenticationResponseValidator with the CertificateValidator
DeviceLinkAuthenticationResponseValidator deviceLinkAuthenticationResponseValidator =
DeviceLinkAuthenticationResponseValidator.defaultSetupWithCertificateValidator(certificateValidator);

// Create authentication request builder
DeviceLinkAuthenticationSessionRequestBuilder authenticationRequestBuilder = smartIdClient.createDeviceLinkAuthentication()...;
DeviceLinkAuthenticationSessionRequestBuilder authenticationRequestBuilder = smartIdClient.createDeviceLinkAuthentication()...;
// Initialize session
DeviceLinkSessionResponse sessionResponse = authenticationRequestBuilder.initAuthenticationSession();
// Get request used for starting the authentication session and use it later to validate sessions status response
Expand All @@ -852,9 +854,13 @@ SessionStatusPoller poller = smartIdClient.getSessionStatusPoller();
SessionStatus sessionStatus = poller.fetchFinalSessionStatus(sessionResponse.sessionID());

// validate sessions state is completed
if("COMPLETE".equals(sessionStatus.getState())){
if ("COMPLETE".equals(sessionStatus.getState())) {
// For same-device flows (Web2App/App2App), get userChallengeVerifier from callback URL
String userChallengeVerifier = "<userChallengeVerifier-from-callback-url>";

// validate the session status response with authentication session request and return authentication identity
AuthenticationIdentity authenticationIdentity = deviceLinkAuthenticationResponseValidator.validate(sessionStatus, authenticationSessionRequest, "smart-id-demo");
AuthenticationIdentity authenticationIdentity =
deviceLinkAuthenticationResponseValidator.validate(sessionStatus, authenticationSessionRequest, userChallengeVerifier, "smart-id-demo");
}
```

Expand All @@ -863,11 +869,12 @@ if("COMPLETE".equals(sessionStatus.getState())){
NotificationAuthenticationResponseValidator depends on CertificateValidator. Checkout [setting up CertificateValidator](#set-up-certificatevalidator)

```java
// Set up AuthenticationResponseValidator with the CertificateValidator
NotificationAuthenticationResponseValidator notificationAuthenticationResponseValidator = new AuthenticationResponseValidator(certificateValidator);
// Set up NotificationAuthenticationResponseValidator with the CertificateValidator
NotificationAuthenticationResponseValidator notificationAuthenticationResponseValidator =
NotificationAuthenticationResponseValidator.defaultSetupWithCertificateValidator(certificateValidator);

// Create authentication request builder
NotificationAuthenticationSessionRequestBuilder authenticationRequestBuilder = smartIdClient.createDeviceLinkAuthentication()...;
NotificationAuthenticationSessionRequestBuilder authenticationRequestBuilder = smartIdClient.createNotificationAuthentication()...;
// Initialize session
NotificationAuthenticationSessionResponse sessionResponse = authenticationRequestBuilder.initAuthenticationSession();
// Get request used for starting the authentication session and use it later to validate sessions status response
Expand All @@ -878,9 +885,10 @@ SessionStatusPoller poller = smartIdClient.getSessionStatusPoller();
SessionStatus sessionStatus = poller.fetchFinalSessionStatus(sessionResponse.sessionID());

// validate sessions state is completed
if("COMPLETE".equals(sessionStatus.getState())){
if ("COMPLETE".equals(sessionStatus.getState())) {
// validate the session status response with authentication session request and return authentication identity
AuthenticationIdentity authenticationIdentity = notificationAuthenticationResponseValidator.validate(sessionStatus, authenticationSessionRequest, "smart-id-demo");
AuthenticationIdentity authenticationIdentity =
notificationAuthenticationResponseValidator.validate(sessionStatus, authenticationSessionRequest, "smart-id-demo");
}
```

Expand Down
Loading