I've been trying for a week to authenticate on Azure Active Directory with a Java application which presents client credential grant, in order to retrieve an access token to target the Outlook Office365 REST API, but could not succeed. The server always returns an error :
com.microsoft.aad.adal4j.AuthenticationException: {"error":"unauthorized_client","error_description":"AADSTS70002: Error validating credentials. AADSTS50064: Credential validation failed
I have followed the MSDN blog post http://blogs.msdn.com/b/exchangedev/archive/2015/01/21/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx and uploaded my public cert in the application manifest on Azure.
I'm using the Java Library ADAL4J in version 0.0.4 with the following code :
service = Executors.newFixedThreadPool(1);
final KeyStore keystore = KeyStore.getInstance("PKCS12", "SunJSSE");
keystore.load(new FileInputStream(MyApp.class.getResource(TestConfiguration.AAD_CERTIFICATE_PATH).getFile()),
TestConfiguration.AAD_CERTIFICATE_PASSWORD.toCharArray());
final String alias = keystore.aliases().nextElement();
final PrivateKey key = (PrivateKey) keystore.getKey(alias, TestConfiguration.AAD_CERTIFICATE_PASSWORD.toCharArray());
final X509Certificate cert = (X509Certificate) keystore.getCertificate(alias);
final AsymmetricKeyCredential asymmetricKeyCredential = AsymmetricKeyCredential.create(TestConfiguration.AAD_CLIENT_ID, key, cert);
ctx = new AuthenticationContext(TestConfiguration.AAD_TENANT_ENDPOINT, false, service);
final Future<AuthenticationResult> result = ctx.acquireToken(TestConfiguration.AAD_RESOURCE_ID, asymmetricKeyCredential,null);
ar = result.get();
Here is my TestConfiguration object :
public final class TestConfiguration {
public final static String AAD_HOST_NAME = "login.windows.net";
public final static String AAD_TENANT_NAME = "MYTENANT.onmicrosoft.com";
public final static String AAD_TENANT_ENDPOINT = "https://" + AAD_HOST_NAME + "/" + AAD_TENANT_NAME + "/";
public final static String AAD_CLIENT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
public final static String AAD_CLIENT_SECRET = "xxxxxxxxxx";
public final static String AAD_RESOURCE_ID = "https://outlook.office365.com/";
public final static String AAD_CERTIFICATE_PATH = "/MyCert.pfx";
public final static String AAD_CERTIFICATE_PASSWORD = "xxxxxxx";
}
Here is the com.microsoft.aad.adal4j.AdalOAuthRequest request object properties produced :
authorization : null
contentType : application/x-www-form-urlencoded; charset=UTF-8
extraHeaderParams : {client-request-id=d942e921-71d7-47ef-9f97-29e8bb4122aa, x-client-OS=Windows 7, x-client-SKU=java, return-client-request-id=true, x-client-CPU=amd64, x-client-VER=1.0}
method : POST
query : client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&grant_type=client_credentials&client_assertion=eyJhbGciOiJSUzI1NiIsIn ... cut ... G0U4MeBV69EGauQ&resource=https%3A%2F%2Foutlook.office365.com%2F
url : https://login.windows.net/mytenant.onmicrosoft.com/oauth2/token
Where may have I missed some thing ?
Thanks for your help.
P.S. : when I download my application manifest back from Azure, I find my "keyCredentials" JSON object but it's "value" property is null (whereas I did previously put my public cert in it) ... Does it mean it is really null or just an empty property for security reasons ??
Exception in thread "main" com.microsoft.aad.adal4j.AuthenticationException: {"error":"unauthorized_client","error_description":"AADSTS70002: Error validating credentials. AADSTS50064: Credential validation failed.\r\nTrace ID: 823ec9e0-7872-4564-a6c0-316dd077eafb\r\nCorrelation ID: 2ab2a724-be32-446b-b343-21fa2c58e7cb\r\nTimestamp: 2015-02-23 19:47:32Z"}- Eric