Authentication with Certificates
The following example script illustrates the process for authentication with username and certificates.
private void loginWithCertificate() {
String username = getUserInput("Username : ");
byte[] clientChallengeBytes = String.valueOf(new Random().nextLong()).getBytes();
String encodedClientChallenge = Base64.encodeBase64URLSafeString(clientChallengeBytes);
MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<String, String>();
requestParams.add("user_name", username);
requestParams.add("auth_type", "server");
requestParams.add("client_challenge", encodedClientChallenge);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(
requestParams, headers);
ServerChallengeResponse challengeResponse = null;
try {
challengeResponse = invokeApiWithPost(RestApi.LOGIN_CERT_SVR, requestEntity,
ServerChallengeResponse.class);
}
catch (RestServiceException e) {
sop("************************************");
sop("Authenticate Server Failed");
sop("************************************");
sop("Error Code: " + e.getError().toString() + "\r\nError: "
+ e.getError().getErrorMessage() + "\r\nDetail : " + e.getMessage());
return;
}
byte[] encryptedClientChallengeBytes = Base64.decodeBase64(challengeResponse
.getClientChallenge());
byte[] serverChallengeBytes = Base64.decodeBase64(challengeResponse.getServerChallenge());
String serverCertName = getUserInput("Enter the name & location of the server certificate : ");
File certFile = new File(serverCertName);
if (!certFile.exists()) {
sop("Server certificate doesn't exist in that location");
return;
}
X509Certificate serverCertificate = null;
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
serverCertificate = (X509Certificate) certFactory
.generateCertificate(new FileInputStream(certFile));
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, serverCertificate.getPublicKey());
byte[] decryptedClientChallengeBytes = decryptCipher
.doFinal(encryptedClientChallengeBytes);
// Compare the clientChallenge with decryptedClientChallenge.
boolean serverValidated = Arrays.equals(clientChallengeBytes,
decryptedClientChallengeBytes);
if (serverValidated) {
sop("Server response validation 'PASSED' ... proceeding further to login to REST service");
}
else {
sop("Server response validation 'FAILED'");
return;
}
}
catch (Exception e) {
sop("Could not process with the ceritificate : " + e.getMessage());
return;
}
// Get the private key of the client certificate
PrivateKey privateKey = getPrivateKeyForClientCertificate();
if (privateKey == null) {
sop("Couldn't get private key from the client certificate");
return;
}
byte[] encryptedServerChallengeBytes = null;
try {
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, privateKey);
encryptedServerChallengeBytes = encryptCipher.doFinal(serverChallengeBytes);
}
catch (Exception e) {
sop("Couldn't encrypt server challenge : " + e.getMessage());
return;
}
requestParams = new LinkedMultiValueMap<String, String>();
requestParams.add("user_name", username);
requestParams.add("auth_type", "client");
requestParams.add("server_challenge",
Base64.encodeBase64URLSafeString(encryptedServerChallengeBytes));
headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.add("Authorization", challengeResponse.getAuthToken());
requestEntity = new HttpEntity<MultiValueMap<String, String>>(requestParams, headers);
LoginResponse loginResponse = null;
try {
loginResponse = invokeApiWithPost(RestApi.LOGIN_CERT_CL, requestEntity,
LoginResponse.class);
}
catch (RestServiceException e) {
sop("************************************");
sop("Login with ceritficate : FAILED");
sop("************************************");
sop("Error Code: " + e.getError().toString() + "\r\nError: "
+ e.getError().getErrorMessage() + "\r\nDetail : " + e.getMessage());
}
if (loginResponse != null) {
String restEndPoint = loginResponse.getEndPoint();
if (!isEmpty(restEndPoint)) {
sop("************************************");
sop("Login with ceritficate : PASSED");
sop("************************************");
this.svcEndPoint = restEndPoint;
this.token = loginResponse.getAuthToken();
}
else {
sop("************************************");
sop("Login with user/pwd : FAILED");
sop("************************************");
sop("Error: RestEndPoint has not been defined for this ARG."
+ "Please check REST API settings in PodConfig.ini.");
}
}
}