Links

Integration and Usage

In this example we use SpringBoot to build the RESTful service. You can view the full code here, and find the SDK here.

Initialization

Include the SDK dependencies to the local Maven repository:
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:
<dependency>
<groupId>com.github.ontio</groupId>
<artifactId>ontlogin-sdk-java</artifactId>
<version>1.0.0</version>
</dependency>

Add API Methods

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)
// 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

@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

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.
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.