# Integration and Usage

{% hint style="info" %}
In this example we use SpringBoot to build the RESTful service. You can view the full code [here](https://github.com/ontology-tech/ontlogin-demo/tree/main/backend/java), and find the SDK [here](https://github.com/ontology-tech/ontlogin-sdk-java).&#x20;
{% endhint %}

## Initialization

Include the SDK dependencies to the local Maven repository:

```java
mvn install:install-file -DgroupId=com.github.ontio -DartifactId=ontlogin-sdk-java -Dversion=1.0.0 -Dpackaging=jar -Dfile=ontlogin-sdk-java-1.0.0.jar
```

Add dependencies in the `pom.xml` file:

```java
        <dependency>
            <groupId>com.github.ontio</groupId>
            <artifactId>ontlogin-sdk-java</artifactId>
            <version>1.0.0</version>
        </dependency>
```

## Add API Methods <a href="#add-api-methods" id="add-api-methods"></a>

Add the methods in the Controller:

* `requestChallenge`: Returns the challenge from the server
* `submitChallenge` : Passes the signed challenge and VP (if requested by the server)&#x20;

```java
    // Challenge request
    @PostMapping("/challenge")
    public Result generateChallenge(@RequestBody ClientHello clientHello) throws Exception {
        String action = "generateChallenge";
        ServerHello result = loginService.generateChallenge(action, clientHello);
        return new Result(action, ErrorInfo.SUCCESS.code(), ErrorInfo.SUCCESS.descEN(), result);
    }

    // Challenge submission
    @PostMapping("/validate")
    public Result validateClientResponse(@RequestBody ClientResponse clientResponse) throws Exception {
        String action = "validateClientResponse";
        String token = loginService.validateClientResponse(action, clientResponse);
        return new Result(action, ErrorInfo.SUCCESS.code(), ErrorInfo.SUCCESS.descEN(), token);
    }

    // Other business logic
    @PostMapping("/check-jwt")
        public Result checkJwt(@RequestBody JSONObject req) {
            String action = "checkJwt";
            String token = req.getString("token");
            loginService.checkJwt(action, token);
            return new Result(action, ErrorInfo.SUCCESS.code(), ErrorInfo.SUCCESS.descEN(), ErrorInfo.SUCCESS.descEN());
        }
```

## Use `loginService`

```java
   @Autowired
    private JWTUtils jwtUtils;
    @Autowired
    private SDKUtil sdkUtil;

    @Override
    public ServerHello generateChallenge(String action, ClientHello clientHello) throws Exception {
        // Invoke the SDK to generate the challenge
        return sdkUtil.generateChallenge(clientHello);
    }

    @Override
    public String validateClientResponse(String action, ClientResponse clientResponse) throws Exception {
        sdkUtil.validateClientResponse(clientResponse);
        // Challenge verification successful
        // Now you can proceed according to your business logic
        // In this example, JWT is used for authentication 
        String token = jwtUtils.signAccess("", "test user");
        return token;

    }

    @Override
    public void checkJwt(String action, String token) {
        jwtUtils.verifyAccessToken(token);
    }
```

## Import `SDKUtil` and Initialize `ontlogin Sdk`

```java
    private OntLoginSdk sdk;
    // To store UUID. In real projects, UUID can be stored in the database, redis or cache
    private Map<String, Integer> nonceMap = new HashMap<>();

    private OntLoginSdk getOntLoginSdk() throws Exception {
        if (sdk == null) {
            synchronized (OntLoginSdk.class) {
                if (sdk == null) {
                    ServerInfo serverInfo = new ServerInfo();
                    serverInfo.setName("testServcer");
                    serverInfo.setIcon("http://somepic.jpg");
                    serverInfo.setUrl("https://ont.io");
                    // Server DID 
                    serverInfo.setDid("did:ont:sampletest");
                    serverInfo.setVerificationMethod("");
                    
                    Map<Integer, VCFilter[]> vcFilters = new HashMap<>();
                    // Configure `VCFilter` according to `actionType`
                    VCFilter vcFilter = new VCFilter();
                    // VC type
                    vcFilter.setType("EmailCredential");
                    // If it's required
                    vcFilter.setRequired(true);
                    // Issuer DID
                    vcFilter.setTrustRoots(new String[]{"did:ont:testdid"});
                    VCFilter[] vcFiltersArray = {vcFilter};
                    vcFilters.put(Const.ACTION_AUTHORIZATION, vcFiltersArray);
                            
                    SDKConfig sdkConfig = new SDKConfig();
                    // Supported chains, e.g. eth, ont, bsc, respective Processors needed
                    sdkConfig.setChain(new String[]{"ont"});
                    // Supported signature scheme
                    sdkConfig.setAlg(new String[]{"ES256"});
                    // Server info
                    sdkConfig.setServerInfo(serverInfo);
                    // VC required by the server
                    sdkConfig.setVcFilters(vcFilters);
                    
                    // Initialize the Processor of the respective chain
                    // Parameter specification using Ontology as an example
                    // 1. doubleDirection bool: if mutual authentication is required
                    // 2. Ontology node rpc server address
                    // 3. DID contract address, can be null when 1 takes `false`
                    // 4. Ontology wallet address, can be null when 1 takes `false`
                    // 5. Wallet password, can be null when 1 takes `false`
                    OntProcessor ontProcessor = new OntProcessor(false, "http://polaris2.ont.io:20334",
                            "52df370680de17bc5d4262c446f102a0ee0d6312", "./wallet.json", "12345678");
                    Map<String, DidProcessor> resolvers = new HashMap<>();
                    resolvers.put("ont", ontProcessor);

                    // Except config, Processor and SDK, the following functions need to be passed
                    // 1. public String genRandomNonceFunc(Integer action): generates UUID by action
                    // 2. public Integer getActionByNonce(String nonce): checks if the nonce (UUID) exists in the database/redis/cache and returns action
                    sdk = new OntLoginSdk(sdkConfig, resolvers) {
                        @Override
                        public String genRandomNonceFunc(Integer action) {
                            String nonce = UUID.randomUUID().toString().replace("-", "");
                            nonceMap.put(nonce, action);
                            return nonce;
                        }

                        @Override
                        public Integer getActionByNonce(String nonce) {
                            Integer action = nonceMap.get(nonce);
                            if (action == null) {
                                throw new OntLoginException("checkNonce", ErrorInfo.NONCE_NOT_EXISTS.descEN(), ErrorInfo.NONCE_NOT_EXISTS.code());
                            }
                            nonceMap.remove(nonce);
                            return action;
                        }
                    };
                }
            }
        }
        return sdk;
    }

    public ServerHello generateChallenge(ClientHello clientHello) throws Exception {
        OntLoginSdk ontLoginSdk = getOntLoginSdk();
        ServerHello serverHello = ontLoginSdk.generateChallenge(clientHello);
        return serverHello;
    }

    public void validateClientResponse(ClientResponse clientResponse) throws Exception {
        OntLoginSdk ontLoginSdk = getOntLoginSdk();
        ontLoginSdk.validateClientResponse(clientResponse);
    }
```

## Handle VP

Use the following to extract VC from VP in form of JSON text.

```java
public String[] getCredentialJsons(String presentation)
```

Since the form of VC varies according to the server's request, only JSON is supported here. The server can parse the VC into the per-defined form.
