# Affinidi Login with Java

> In this guide, learn how to enable passwordless login in your application using Java and Springboot framework.

The Affinidi Login is a passwordless authentication solution that verifies user identity using [Affinidi Vault](/products/affinidi-elements/affinidi-vault/how-affinidi-vault-works.md) as the identity provider managed by the end-user.

In this lab, we will use [JAVA 21](https://jdk.java.net/21/) and [Springboot](https://spring.io/) from the available sample applications to take you through the step-by-step guide for creating a Login Configuration and setting up the application to implement passwordless authentication for end-users.

## Before you begin

- Set up Affinidi Vault account. Follow the guide below if you haven’t set it up yet.

        Set up Affinidi Vault

Set up an Affinidi Vault account using the [Web Vault](https://vault.affinidi.com) or install the Mobile Vault (for [Android](https://play.google.com/store/apps/details?id=com.affinidi.vault&pcampaignid=web_share)).

The same setup steps for Mobile Vault.

- 
Click on Get started if you are creating a new account, or click on Restore from Backup if you have an existing backup of your Affinidi Vault. Provide the passphrase to secure your Affinidi Vault.

You have the option to enable Biometrics to unlock your Affinidi Vault easily instead of using passphrase.

GIF 

- Enter your email address to register with the Affinidi Vault. An OTP will be sent to this email for verification.

GIF 

- Enter the OTP sent to the email you have provided for verification to complete the setup.

GIF 

After successfully providing the OTP, you are redirected to the Affinidi Vault dashboard.
Important Note

Remember to keep your passphrase in a secure location. Use the Passphrase Reset feature in Affinidi Vault settings to generate the PDF files and keep them safe, which you can use to recover access to your Affinidi Vault if you forget your passphrase.

- 
Get the Redirect URI of your application for OIDC. This is the URI configured on your Login Configuration to receive the idToken after successful authorisation.

- 
Optionally, Install the Affinidi CLI. Follow the guide below if it hasn’t been installed.

        Set up Affinidi CLI

- Download and install [NodeJS](https://nodejs.org/en/download) on your machine if you haven’t set it up yet.

Node Version

Affinidi CLI requires Node version 18 and above.

- Install Affinidi CLI using Node Package Manager (npm).

```bash
npm install -g @affinidi/cli
```

- Verify that the installation is successful.

```bash
affinidi --version
```

- Install JAVA 21 on your machine if you haven’t installed yet using [this guide](https://jdk.java.net/21/).

## Download Application

You can [clone](https://github.com/affinidi/reference-app-affinidi-vault/tree/main/samples/affinidi-java-springboot) this sample application from our Github and start exploring how to integrate Affinidi Login to provide a passwordless login experience for your end-users.

    Important Note
    The downloadable sample application is provided only as a guide to quickly explore and learn how to integrate the components of Affinidi Trust Network into your application. This is NOT a Production-ready implementation. Do not deploy this to a production environment.

## Create Login Configuration

To create a [Login Configuration](/products/affinidi-elements/affinidi-login/login-configuration.md), you can either use Affinidi CLI or [Affinidi Portal ](/dev-tools/affinidi-portal.md#create-a-login-configuration).

Expand the section below for your preferred method:

Java Springboot App Settings:

Name: Java Springboot App

Redirect URIs: http://localhost:8080/login/oauth2/code/javademo

Expand the section below for your preferred method:

        Using Affinidi CLI

- Log in to Affinidi CLI by running:

```Bash
affinidi start
```

- Once you have successfully logged in, create the Login Configuration by running:

```Bash
affinidi login create-config --name='Java Springboot App' --redirect-uris='http://localhost:8080/login/oauth2/code/javademo'
```

- --name is what you want your login configuration to be called.

- --redirect-uris is the URL on your application where the user gets redirected after the successful authentication.

Learn more on how to manage your Login Configurations using [Affinidi CLI](/dev-tools/affinidi-cli.md#affinidi-vpa-configs).

        Using Affinidi Portal

- 
Go to [Affinidi Login ](https://portal.affinidi.com/affinidiLogin) under the Services section.

- 
Click on the Create Login Configuration and provide the required details.

- Name is the string that describes your login configuration.

- Redirect URIs is the URL on your application where the user gets redirected after the successful authentication.

- 
Click on create and confirm if all the details are correct.

- 
After confirming the details, another popup shows the Client ID and Client Secret for your Login Configuration. Copy the generated Client Credentials and use them to integrate with Affinidi Login.

- After copying the Client ID and Client Secret and closing the popup, you are redirected back to the Affinidi Login page.

Login Configuration uses the default Presentation Definition (presentationDefinition) and ID Token Mapping (idTokenMapping) that is used to request the user’s email address during the authentication flow.

Learn more about customising the Presentation Definition and ID Token using [this guide](/products/affinidi-elements/affinidi-login/presentation-definition-id-token-mapping.md).

    Important

Safeguard the Client ID and Client Secret diligently; you'll need them for setting up your IdP or OIDC-compliant applications. Remember, the Client Secret will be provided only once.

## Set up the Sample Application

After creating the Login Configuration required to set up the sample application. Let’s start setting up the Java application by configuring the following settings:

#### Configure Env Variables

Create the .env file using the following command:

```Bash
cp .env.example .env
```

Set the environment variables based on the auth credentials received from the Login Configuration created earlier:

```JSON
{
  "auth": {
    "clientId": "",
    "clientSecret": "",
    "issuer": "https://

.apse1.login.affinidi.io"
  }
}
```

Set the following fields in the .env file

```yaml
PROVIDER_CLIENT_ID=
PROVIDER_CLIENT_SECRET=
PROVIDER_ISSUER=
```
Note

Do not enclose the above values with double quotes ("") while updating. As an example, below is your .env should look like below.

```yaml
PROVIDER_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxx
PROVIDER_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxx
PROVIDER_ISSUER=https://xxxxxxxxxxxxxxxxxxxxx.apse1.login.affinidi.io
```

#### Build and Run

```sh
sh mvnw clean
sh mvnw install
sh mvnw spring-boot:run
```

After successfully running the command, go to [http://localhost:8080/](/) to access the page with the Affinidi Login button.

## Key Changes to Sample Application

To enable a seamless passwordless login experience with Affinidi Login, refer to the following key changes were implemented:

- Registered javademo as the oauth2 client provider in the ./src/main/resources/application.yml including the client credentials.

```YAML
spring:
  security:
    oauth2:
      client:
        registration:
          javademo:
            client-name: Affinidi Login
            client-id: ${PROVIDER_CLIENT_ID}
            client-secret: ${PROVIDER_CLIENT_SECRET}
            redirect-uri: http://localhost:8080/login/oauth2/code/javademo
            scope: openid,offline_access
            client-authentication-method: client_secret_post
            provider: afflogin
        provider:
          afflogin:
            issuer-uri: ${PROVIDER_ISSUER}
  config:
    import:
      optional:file:.env[.properties]          
logging:
  level:
     org.springframework: WARN
     login.affinidi: INFO
server:
    port: 8080
```

- Implemented the following method in the ./java/login/affinidi/client/controller/UserController.java:

- user method to extract the user claims from the ID Token provided by the Affinidi Login.

- populateModel method populates the user model from the ID Token to display on UI.

```Java
package login.affinidi.client.controller;
import java.util.ArrayList;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.nimbusds.jose.shaded.gson.internal.LinkedTreeMap;

@Controller
public class UserController {

    @GetMapping("/")
    public String index(){
        return "index";
    }
    /**
     * This method acts as handler for /user endpoint. It extracs details from
     * authenticator oidc user for user interface
     * 
     * @param model
     * @param oidcUser
     * @return
     */
    @GetMapping("/user")
    public String user(Model model,
                        @AuthenticationPrincipal OidcUser oidcUser) {
        @SuppressWarnings("unchecked")
        ArrayList
- > customNodeFromToken = 
            (ArrayList
- >)oidcUser.getAttributes().get("custom");
        populateModel(customNodeFromToken, model);
        return "user";
    }
    /**
     * This method extracts every populated attribute from custom node of idToken
     * and adds it to UI model for display
     * 
     * @param customNodeFromToken
     * @param model
     */
    private void populateModel(ArrayList
- > customNodeFromToken, Model model){
        for(LinkedTreeMap eachAttribute : customNodeFromToken){
            if(eachAttribute != null){
                for(String key : eachAttribute.keySet()){
                    model.addAttribute(key, eachAttribute.get(key));
                }
            }
        }
    }
}
```

## Summary

```mermaid
sequenceDiagram
    actor User
    participant Java
    participant Affinidi Login
    participant Affinidi Vault
    participant Affinidi Verifier

    User->>Java: My Login
    Java->>Affinidi Login: Authenticate user
    Note over Java, Affinidi Login:  login_challenge
    Affinidi Login->>Affinidi Vault: Verify user identity
    Note over Affinidi Login, Affinidi Vault:  presentationDefinition
    Affinidi Vault->>User: Request user confirmation to share Email VC
    User->>Affinidi Vault: User confirmed consent to share Email VC
    Affinidi Vault->>Affinidi Vault: Generate VP Token from VC
    Affinidi Vault->>Affinidi Login: Send Email VP Token
    Affinidi Login->>Affinidi Verifier: Validate VP Token
    Note over Affinidi Login, Affinidi Verifier:  vp_token, presentation_submission, presentation_definition
    Affinidi Login->>Affinidi Login: Generate idToken
    Affinidi Login->>Java: Send generated idToken from VP
    Java->>User: Provide access to the user
```

Using the Java and Springboot as the sample application, we have configured it to integrate with Affinidi Login as the Auth provider and parse the idToken sent by the Affinidi Login to confirm the user’s successful authentication using the Affinidi Vault.
