2

I'm encountering a problem. I am using Microsoft Graph to get the current logged in user via OnBehalfOfMsGraphAuthenticationProvider.cs as seen in the following solution.

This has been working flawlessly, but I have been doing some refactoring, and suddenly I get an error when trying to execute my authContext.AcquireTokenAsync() method.

HTTP Error 502.3 - Bad Gateway

The code in question looks like this:

public async Task AuthenticateRequestAsync(HttpRequestMessage request) {
    var httpContext = _httpContextAccessor.HttpContext;

    //Get the access token used to call this API
    string token = await httpContext.GetTokenAsync("access_token");

    //We are passing an *assertion* to Azure AD about the current user
    //Here we specify that assertion's type, that is a JWT Bearer token
    string assertionType = "urn:ietf:params:oauth:grant-type:jwt-bearer";

    //User name is needed here only for ADAL, it is not passed to AAD
    //ADAL uses it to find a token in the cache if available
    var user = httpContext.User;
    string userName =
        user.FindFirst(ClaimTypes.Upn).Value ?? user.FindFirst(ClaimTypes.Email).Value;

    var userAssertion = new UserAssertion(token, assertionType, userName);

    //Construct the token cache
    var cache = new DistributedTokenCache(user, _distributedCache,
        _loggerFactory, _dataProtectionProvider);

    var authContext = new AuthenticationContext(_configuration["AzureAd:Instance"] +
        _configuration["AzureAd:TenantId"], true, cache);

    var clientCredential = new ClientCredential(_configuration["AzureAd:ClientId"],
        (string) _configuration["AzureAd:ClientSecret"]);

    //Acquire access token
    var result = await authContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential, userAssertion); //This is where it crashes

    //Set the authentication header
    request.Headers.Authorization = new AuthenticationHeaderValue(result.AccessTokenType, result.AccessToken);
}

I am calling it from my OrdersController:

// POST: api/Orders
[HttpPost]
public async Task<IActionResult> CreateAsync([FromBody] OrderDTO order) {
        if (!ModelState.IsValid) {
            return BadRequest(ModelState);
        }

        var graphUser = await this.graphApiService.GetUserProfileAsync();

The refactoring has consisted of dividing my solution into two class library projects and one web project - the latter has the controllers and the React app. GraphAPiClient and the provider are located in the Core library like this:

Screenshot of architecture

Marc LaFleur
  • 31,987
  • 4
  • 37
  • 63
C_Karlslund
  • 329
  • 3
  • 12
  • May be this is authentication issue https://stackoverflow.com/a/38754821/10634638 – estinamir Dec 04 '18 at 14:55
  • 1
    What is the output of `_configuration["AzureAd:Instance"] + _configuration["AzureAd:TenantId"]`? – Marc LaFleur Dec 04 '18 at 16:29
  • @MarcLaFleur: I have checked, and the output is correct. They both correspond with the correct GUIDs (I don't want to type them out because of security reasons). – C_Karlslund Dec 05 '18 at 06:48
  • @bestinamir Thank you for your answer! This is not a call to https://login.microsoftonline.com, however - when this problem arises, I have already done that call successfully, and now I want to call Graph API using the token I got. This has worked before - the thing that puzzles me is the strange error I get. – C_Karlslund Dec 05 '18 at 06:50
  • The authority shouldn't be two GUIDs, it should be a URI to the issuer of the token. eg. `https://login.microsoftonline.com/{tenant-name}.onmicrosoft.com` – Marc LaFleur Dec 05 '18 at 17:58
  • @MarcLaFleur Thank you for your reply! However, when my problem arises I have already done a successful call to login.microsoftonline.com. The flow, as seen [here](https://learn.microsoft.com/en-us/graph/auth-v2-user) is the following: 1. Register your app with Azure AD. 2. Get authorization. 3. Get an access token. 4. Call Microsoft Graph with the access token. 5. Use a refresh token to get a new access token. The call using the GUIDs belong to #4, and makes a call to "https://graph.microsoft.com". More [here](https://github.com/AzureAD/azure-activedirectory-library-for-dotnet). – C_Karlslund Dec 06 '18 at 07:13
  • This is the line I was asking about `var authContext = new AuthenticationContext(_configuration["AzureAd:Instance"] + _configuration["AzureAd:TenantId"], true, cache);`. T – Marc LaFleur Dec 06 '18 at 19:30
  • Sorry, my bad! Yes, the instance is indeed "https://login.microsoftonline.com/" while the tenantid is a GUID. – C_Karlslund Dec 07 '18 at 07:45

2 Answers2

2

So, it turns out that the problem appeared when I upgraded the package Microsoft.IdentityModel.Clients.ActiveDirectory from v3.19.8 to v4.4.1. For some reason, no versions above v3.19.8 work with my code, causing it to crash when I try to make the call to https://graph.microsoft.com, but as soon as I downgraded the problem disappeared.

C_Karlslund
  • 329
  • 3
  • 12
-2

Try using AcquireToken instead of AcquireTokenAsync

azureAuthenticationContext.AcquireToken
Madhu
  • 415
  • 1
  • 4
  • 15
  • 1
    Thank you for your answer! Unfortunately, AuthenticationContext does not contain a definition for AcquireToken. [link](https://learn.microsoft.com/en-us/dotnet/api/microsoft.identitymodel.clients.activedirectory.authenticationcontext?view=azure-dotnet) – C_Karlslund Dec 04 '18 at 15:21
  • Ok, My bad.. AcquireToken is in Microsoft.IdentityModel.Clients.ActiveDirectory(V2.28.3.860) used in .NET framework projects. Here is the code that works in .NET Core `azureAuthenticationContext.AcquireTokenAsync(resource, cred).Result`. Try installing this package "Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Version 4.4.1" – Madhu Dec 04 '18 at 16:35
  • Thank you, but this is exactly what I have been doing so far. Unfortunately, it doesn't work! – C_Karlslund Dec 05 '18 at 06:52