我已经尝试用一周的时间在Azure Active Directory上使用Java应用程序进行身份验证,该应用程序提供客户端凭据授予,以便检索访问令牌以定位Outlook Office365 REST API,但无法成功。 服务器始终返回错误:
com.microsoft.aad.adal4j.AuthenticationException: {"error":"unauthorized_client","error_description":"AADSTS70002: Error validating credentials. AADSTS50064: Credential validation failed
我已关注MSDN博文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并将我的公共证书上传到Azure上的应用程序清单中。
我在版本0.0.4中使用Java库ADAL4J,代码如下:
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();
这是我的TestConfiguration对象:
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";
}
以下是生成的com.microsoft.aad.adal4j.AdalOAuthRequest请求对象属性:
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
我可能在哪里遗漏了一些东西?
感谢您的帮助。
P.S。 :当我从Azure下载我的应用程序清单时,我找到了我的“keyCredentials”JSON对象,但是它的“value”属性为null(而我之前确实把我的公共证书放在其中)...这是否意味着它真的是null或者出于安全原因只是一个空房子?
答案 0 :(得分:0)
commons-codec版本需要从1.4更新到1.5才能使编码正常工作。 http://commons.apache.org/proper/commons-codec/changes-report.html#a1.5
从ERIC编辑
我终于设法通过将我的common-codecs工件从1.4(它不能正常工作)升级到1.5来检索访问令牌。
我们考虑了通用编解码器工件,因为所提供的JWT令牌具有公共证书值,其中包含&#34; \ r \ n&#34;在我的应用生成时插入,而在从专用的示例测试应用生成时却没有。
那些&#34; \ r \ n&#34;字符被插入&#34; x5c&#34;通过从com.microsoft.aad.adal4j.AsymmetricKeyCredential.getPublicCertificate()调用org.apache.commons.codec.binary.Base64.encodeBase64String(byte [])来获取JWT头属性。
似乎我的应用程序已经依赖于common-codecs v1.4,这对于adal4j来说并不合适。