在 Java 中验证 Azure AD 签名

Validating Azure AD Signature in Java

我是一名相当有经验的 Java 开发人员(4-5 年),但对 Azure AD 及其功能还很陌生,所以对于一个潜在的基本问题,我提前表示歉意。我一直在努力在 Java 中找到涵盖该主题的任何 Microsoft 文档或 Stack Overflow 问题(绝大多数在 C# 中),据我了解,C# 的 Azure AD 库多于 Java,因此解决方案在C# 不一定是 Java.

中的解决方案

我正在尝试根据一个场景完成身份验证 POC,在这个场景中,我想将现有的 Azure AD 系统充满用户,我想将其用作身份验证点。我的 Java 应用程序将收集用户的用户名和密码(我知道这已被弃用且不理想,但出于遗留原因需要)并使用 Microsoft adal4j 库调用我可以成功访问的 Azure 端点return JWC 访问令牌(除了刷新和 ID 令牌)。

这是我现有的用于检索 JWC 访问令牌的代码片段。

private static AuthenticationResult getAccessTokenFromUserCredentials(String username, String password, String 
AUTHORITY, String CLIENT_ID) throws Exception {
    AuthenticationContext context = null;
    AuthenticationResult result = null;
    ExecutorService service = null;
    try {
        service = Executors.newFixedThreadPool(1);
        context = new AuthenticationContext(AUTHORITY, false, service);
        Future<AuthenticationResult> future = context.acquireToken(
                "https://graph.windows.net", CLIENT_ID, username, password,
                null);
        result = future.get();
    } finally {
        service.shutdown();
    }

    if (result == null) {
        System.out.println("ex)");
    }
    return result;
}

public void azureAuthenticate(String authority, String clientID, String username, String password){
    AuthenticationResult result = null;
    try {
        result = getAccessTokenFromUserCredentials(username, password, authority, clientID);
        DecodedJWT accessToken = JWT.decode(result.getAccessToken());
        //Want to verify the validity of this access token
    } catch (Exception ex) {
        ex.printStackTrace();
    }

}

我的代码主要基于此Microsoft documentation

收到令牌后,我需要能够验证其真实性(我了解确认其声明的业务逻辑方面,但我对如何验证签名是否合法感到困惑)。

提前感谢您的帮助,我很乐意提供任何需要的说明。

来自 Azure AD 的访问令牌是一个 JSON Web 令牌 (JWT),由安全令牌服务在私钥中签名。 JWT token is a non-encrypted digitally signed JSON payload which contains different attributes (claims) to identify the user. The signature is the last part of the JWT and needs to be used for verification of the payload. This signature was generated with the algorithm described in the header(RS256 if issued from AAD) to prevent unauthorised access.Please refer to this document 有关 JWT 令牌的更多详细信息。

要验证签名,首先我们应该检索并缓存唱歌令牌(public 密钥):1)第一次调用是发现端点。它的 URL 形成为 '/.well-known/openid-configuration' .2) 然后你会在这里找到很多元数据,包括发行者值和 jwks_uri 端点地址,以获取验证令牌的密钥签名 .

令牌签名是根据 JSON Web Key spec. Using Key ID and X.509 certificate thumbprint values from the token's header (kid and x5t parameters respectively) and then find the appropriate public key in the obtained collection of keys to verify the signature. I am not familiar with java ,but you could refer to 实现的,其中包括有关如何在 Java 中验证签名的代码示例。