如何使用MSAL4J为守护程序获取令牌?

时间:2020-04-10 23:21:40

标签: java msal adal4j

我有一个用Java编写并在AWS上运行的守护程序。 对于我支持的100个用户帐户,它使用基于客户端ID,客户端机密和租户ID的令牌来调用多个Microsoft API。与MS Azure Java的Active Directory库(ADAL4J)一起运行都很好。但这已经过去了,因此我被迫转到MS Java身份验证库(MSAL4J)。

基本上,我需要使用客户端ID,机密信息和租户来获取MS API所需的accessToken。

在遍历示例(其中有许多可以编译)之后,似乎这是我可以得到的最接近的代码:

    public static String getToken( String apiUrl, 
            String clientId, 
            String clientSecret,
            String tenantId,
            String authUrl ) {

        String token = null ;

        if ( !authUrl.endsWith("/")){
            authUrl = authUrl + "/" ;
        }
/*
  NOTE: This is derived from the following:
  https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=java

  I simplified the code by taking out the SilentParameters support.

*/

        // BAD:  authUrl = authUrl + "organizations/";
        // BAD:  authUrl = "https://login.microsoftonline.com/" + tenantId + "/";
        // BAD:  authUrl = "https://login.microsoftonline.com/organizations/";
        authUrl = "https://login.microsoftonline.com/organizations/" + tenantId + "/" ;

        // BAD:  Set<String> SCOPE = Collections.singleton("https://graph.microsoft.com/.default");
        // BAD:  Set<String> scope = Collections.singleton(clientId);
        Set<String> scope = Collections.singleton("");

        // Load token cache from file and initialize token cache aspect. The token cache will have
        // dummy data, so the acquireTokenSilently call will fail.
        ITokenCacheAccessAspect tokenCacheAspect = new TokenPersistence("");

        PublicClientApplication pca;
        try {
            pca = PublicClientApplication 
            .builder(clientId)
            .authority(authUrl)
            .setTokenCacheAccessAspect(tokenCacheAspect)
            .build();
        } catch (MalformedURLException e) {
            return null ;
        }

        IAuthenticationResult result;

        /*
        BAD:  ClientCredentialParameters parameters =
        BAD:     ClientCredentialParameters
        BAD:         .builder(SCOPE)
        BAD:         .build();
        */
        UserNamePasswordParameters parameters =
                    UserNamePasswordParameters
                    .builder(scope, clientId, clientSecret.toCharArray())
                    .build();

        result = pca.acquireToken(parameters).join();

        token = result.accessToken() ;
        return token ;
    }

因此,它可以编译(甚至BAD注释掉的代码也可以编译),并且可以运行,但是它生成:

com.microsoft.aad.msal4j.MsalClientException: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.microsoft.aad.msal4j.InstanceDiscoveryMetadataEntry]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)

以上是在 acquireToken 调用(靠近底部)上生成的。

我无法弄清楚哪些代码需要默认的构造函数(使JSON满意)。 太太,我不知道这些是否是我应该拨打的电话;似乎有47种不同的方式可以遍历此MSAL内容,而且我不确定是否找到了“正确的路径”。

Obi-Wan Kenobi,请帮助我。你是我唯一的希望!

2 个答案:

答案 0 :(得分:1)

签出ms-identity-java-daemon示例:https://github.com/Azure-Samples/ms-identity-java-daemon

答案 1 :(得分:0)

尝试完全不使用api.redrawRows(),看看是否可行?即像这样:

TokenCacheAccessAspect

IClientCredential credential = ClientCredentialFactory.createFromSecret(clientSecret); ConfidentialClientApplication cca = ConfidentialClientApplication.builder(clientId, credential) .authority(authUrl) .build(); Set<String> scope = ImmutableSet.of(); ClientCredentialParameters parameters = ClientCredentialParameters.builder(scope) .build(); result = cca.acquireToken(parameters).join(); 应该看起来像authUrl的地方

请参阅:https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-daemon-acquire-token?tabs=java