2017-06-29 52 views
0

我們想利用AcquireTokenAsync使用以下語法使用什麼令牌來產生AAD UserAssertion在C#

public static async Task<UserTokenCache> GetAccessTokens(string userUniqueId) 
    { 
     UserTokenCache cache = null; 
     AuthenticationContext authContext = null; 
     ClientCredential credential = new ClientCredential(clientId, appKey); 
     AuthenticationResult powerBIResult = null; 
     AuthenticationResult graphResult = null; 
     bool isAdalException = false; 
     try 
     { 
      authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userUniqueId)); 

      powerBIResult = await authContext.AcquireTokenSilentAsync(pbiResourceID, credential, new UserIdentifier(userUniqueId, UserIdentifierType.UniqueId)); 

      graphResult = await authContext.AcquireTokenSilentAsync(graphResourceId, credential, new UserIdentifier(userUniqueId, UserIdentifierType.UniqueId)); 

      cache = new UserTokenCache 
      { 
       GraphAccessToken = graphResult.AccessToken, 
       PBIAccessToken = powerBIResult.AccessToken, 
       PBITokenExpires = powerBIResult.ExpiresOn, 
       GraphTokenExpires = graphResult.ExpiresOn 
      }; 

     } 
     catch (JsonException je) 
     { 
      ExceptionLogger.LogInApplicationInsight(je); 
      HttpContext.Current.GetOwinContext().Authentication.Challenge(
         new AuthenticationProperties(), 
         OpenIdConnectAuthenticationDefaults.AuthenticationType); 
     } 
     catch (AdalException ae) 
     { 
      ExceptionLogger.LogInApplicationInsight(ae); 
      if (ae.ErrorCode == "failed_to_acquire_token_silently") 
      { 
       isAdalException = true;  
      } 
      else 
      { 
       HttpContext.Current.GetOwinContext().Authentication.Challenge(
          new AuthenticationProperties(), 
          OpenIdConnectAuthenticationDefaults.AuthenticationType); 
      } 
     } 
     catch (Exception ex) 
     { 
      ExceptionLogger.LogInApplicationInsight(ex); 
     } 
     if(isAdalException) 
     { 
      try 
      { 

       string cacheValue = Convert.ToString(cacheManager.get(userUniqueId)); 
       string decryptedCache = CryptographyUtility.Decrypt(cacheValue); 
       cache = JsonConvert.DeserializeObject<UserTokenCache>(decryptedCache); 

       UserAssertion pbiAssertion = new UserAssertion(cache.PBIAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", UserProperties.UserName); 
       UserAssertion graphAssertion = new UserAssertion(cache.GraphAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", UserProperties.UserName); 

       cache = null; 

       powerBIResult = await authContext.AcquireTokenAsync(pbiResourceID, credential, pbiAssertion); 
       graphResult = await authContext.AcquireTokenAsync(graphResourceId, credential, graphAssertion); 

       cache = new UserTokenCache 
       { 
        GraphAccessToken = graphResult.AccessToken, 
        PBIAccessToken = powerBIResult.AccessToken, 
        PBITokenExpires = powerBIResult.ExpiresOn, 
        GraphTokenExpires = graphResult.ExpiresOn 
       }; 
      } catch (Exception ex) 
      { 
       ExceptionLogger.LogInApplicationInsight(ex); 
      } 
     } 
     return cache; 

    } 

獲得代表用戶的令牌如果我們使用cache.PBIAccessToken和cache.GraphAccessToken到計算在AcquireTokenAsync方法中使用的用戶聲明,它會拋出TenantId不匹配的錯誤。在這種情況下,需要使用什麼標記來計算UserAssertion。

+0

根據這個github的例子看來你需要用戶的訪問令牌。見133至137行,並與你的比較。 https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof/blob/master/TodoListService/Controllers/TodoListController.cs – Shelby115

+0

@ Shelby115,謝謝你的回答。但BootstrapContext在我的情況下是空的。 –

+0

我添加了system.identityModel塊顯示[這裏](http://bartwullems.blogspot.in/2013/08/the-configuration-section-cannot-be.html)。仍然沒有運氣 –

回答

0

通常,我們通常使用AcquireTokenAsync在用戶第一次登錄時獲取訪問令牌和刷新令牌。之後,您可以靜默地獲取令牌(調用AcquireTokenSilentAsync以獲取accessToken),它將從TokenCache獲取令牌或靜默使用refreshToken。如果訪問令牌和刷新令牌都已過期,您可能會收到AdalSilentTokenAcquisitionException(無法靜默獲取令牌,調用方法AcquireToken)。

然後,你可以捕獲該異常,並調用HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" },OpenIdConnectAuthenticationDefaults.AuthenticationType);重定向用戶到蔚藍廣告登錄頁面,登錄後,與AcquireTokenSilentAsync用戶調用的API將工作,因爲在高速緩存中訪問令牌/刷新令牌,並沒有過期。如果我正確理解了您的要求,您的if(isAdalException)中的代碼就沒用了。