如何在多线程应用程序中管理ADAL身份验证令牌的检索

时间:2016-01-24 17:16:40

标签: java multithreading azure azure-active-directory adal

我有基于Java的高容量多线程应用程序,它需要在使用“Azure ADAL AcquireToken”检索的标头中使用授权令牌调用在Microsoft云上运行的基于REST的端点。我正在使用“AzureAD / azure-activedirectory-library-for-java”(下面的代码示例)。我遇到的问题是 -

  1. 我是否需要使用acquireToken进行调用以检索令牌         我将要进行的每个REST调用的方法?如果是,那么         我相信我将通过最新电话获得的令牌可能会改变,         那么在这种情况下是我已经提出请求的请求         以前检索到的令牌将失败或Azure ADAL将         仍然会尊重以前生成的所有令牌?
  2. 如果以前检索到的令牌不会受到Azure的尊重 ADAL然后我有什么选择一次管理单个令牌     然后确保一次只有一个令牌被所有人使用     要求?我是否需要实现某种单线程缓存     要检索令牌,维护该令牌直到它过期,制作一个令牌     如果过期则调用获取新令牌并使我的所有多线程     请求通过此单线程缓存获取最新信息     令牌?对此提出任何建议。如果是这种情况,那么它似乎     喜欢高容量多线程多jvm的巨大瓶颈     应用程序就可扩展性而言。
  3. 我的代码如下。当我从main方法中的循环调用acquireToken方法时,我在10个调用中大多有3种不同类型的令牌,并且所有3种不同的令牌似乎都有效,但不确定它是否应该在多线程应用程序中调用它。

    package com.mycompany.msft.auth;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    import com.microsoft.aad.adal4j.AuthenticationContext;
    import com.microsoft.aad.adal4j.AuthenticationResult;
    import com.microsoft.aad.adal4j.ClientCredential;
    
    public class ApplicationAuthExample {
        private final static String AUTHORIZATION_ENDPOINT = "https://login.microsoftonline.com/";
        private final static String ARM_ENDPOINT = "https://myendpoint";
    
    
        private static String credential = "my credential";
        private static String clientId = "my client id";
        private static String tenantId = "my tenant id";
    
        private static String url = AUTHORIZATION_ENDPOINT + tenantId ;
    
        AuthenticationContext context = null;
        AuthenticationResult result = null;
        ExecutorService service = null;
    
        public  AuthenticationResult getAuthToken() {
            try {
                service = Executors.newFixedThreadPool(1);
    
    
                context = new AuthenticationContext(url, false, service);
    
                Future<AuthenticationResult> future = null;
    
    
                    ClientCredential cred = new ClientCredential(clientId, credential);
                    future = context.acquireToken(ARM_ENDPOINT, cred, null);
    
    
                result = future.get();
            } catch (Exception ex) {
                System.out.println("Exception occurred:");
                ex.printStackTrace();
                System.exit(1);
            } finally {
                service.shutdown();
            }
            return result;
        }
    
        public static void main(String[] args) throws Exception {
    
            ApplicationAuthExample auth = new ApplicationAuthExample();
    
            for (int i =0 ; i< 10 ; i++) {
                AuthenticationResult result = auth.getAuthToken();
                // use adal to Authenticate
    
                System.out.println (i+ " Authorization" + "Bearer " + result.getAccessToken());
                System.out.println (i + " getExpiresOn" + result.getExpiresOn());
    
                //This token comes different in different calls. Which one should I use and which one not. 
                System.out.println (i+ " getExpiresOn" + result.getRefreshToken());
    
    
                System.out.println (i+" getExpiresOn" + result.getUserInfo());
                }
    
        }
    }
    

1 个答案:

答案 0 :(得分:0)

根据我的经验,我认为问题的关键是令牌的到期时间。您可以在到期后使用令牌作为您的愿望。您可以参考https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-tokens/Issued At部分,了解该令牌声称时间包括Expriation Timeadal4j&amp; “不是之前。”

因此,您需要使用Content-Type: application/json, application/x-www-form-urlencoded获取令牌,并在前一个令牌到期时请求刷新令牌。

  

使用AD FS 2.0进行基于声明的身份验证部署的默认安全令牌的生存期为60分钟。

如果要增加Azure AD的令牌过期时间,可以尝试引用文档https://technet.microsoft.com/en-us/library/gg188586.aspx来配置信赖方令牌生存期。