简体   繁体   中英

Bearer token not working when calling web api in Azure

I am having issues getting my API App call work from my Web App in Azure. Here is how things are structured -

  1. Asp.Net Core 1.1 Web App protected by Azure AD authentication - Running locally using Kestrel

StartUp.cs of the web app has following code for getting the token to the web api

        app.UseCookieAuthentication(); 
        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            ClientId = ClientId, //Client Id of my current web app
            ClientSecret = ClientSecret, //ClientSecret of my current web app
            Authority = "https://login.microsoftonline.com/tenantguid",                CallbackPath = Configuration[Constants.ApplicationProxyCallbackPath],
            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            Events = new OpenIdConnectEvents
            {
                OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,
                OnRemoteFailure = OnAuthenticationFailed
            }
        });

For the OnAuthorizationCodeReceived method, this is my code

private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
    {
        string userObjectId = (context.Ticket.Principal.FindFirst(Constants.ClaimsSchemaUri))?.Value;
        ClientCredential clientCred = new ClientCredential(ClientId, ClientSecret);
        AuthenticationContext authContext = new AuthenticationContext(Authority, new NaiveSessionCache(userObjectId, context.HttpContext.Session));
        AuthenticationResult authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
            context.ProtocolMessage.Code,
            new Uri(context.Properties.Items[OpenIdConnectDefaults.RedirectUriForCodePropertiesKey]),
            clientCred,
            WebAPIClientId);        
     }

Using the above code I can successfully get bearer token.

  1. Controller class where I make a call to WebApi

      Task<string> results = null; string resultSet = String.Empty; AuthenticationResult authResult = null; string userObjectID = (currentUser.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier"))?.Value; AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userObjectID, current.Session)); ClientCredential credential = new ClientCredential(Startup.ClientId, Startup.ClientSecret); authResult = await authContext.AcquireTokenSilentAsync(Startup.SearchAPIClientId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId)); //var callerIdentity = currentUser.Identity as WindowsIdentity; HttpClientHandler handler = null; //Setup async action Action action = () => { handler = new HttpClientHandler() { AllowAutoRedirect = true }; //Setup for windows authentication var client = new HttpClient(handler); //Add common http headers client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"); client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate"); client.DefaultRequestHeaders.Add("Accept-Language", "en-US,en;q=0.8"); client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); results = client.GetStringAsync("https://myapi.azurewebsites.net/api/search/"); }; action.Invoke(); resultSet = await results as string; 

The call to the API is re-directed to login.microsftonline.com which means my token was not understood.

  1. The Web API is protected with Azure Authentication using the OpenIdConnect package in code, just like Web App code above .

I had a look at the several related posts, but nothing works fine.

Update 1 - Updated Web API to use JWTBearer Authentication Now the bearer token I acquired in Web App is able to successfully authenticate me to the Web API.

My Web API is expected to call another custom API which is also protected by Azure AD authentication. I am looking to acquire a token for the same, but in order to initiate that I am getting issue while using acquire token for the additional custom API. It's throwing Internal Server 500 with no message. Any thoughts?

Update 2 - Detailed Error On trying to acquire token for the third api, I am getting following exception - "AADSTS50105: Application 'source client id guid' is not assigned to a role for the application 'target client id guid'."

The issue has been fixed and this is what I had to do.

  1. API App authentication changes

    • Changed the authentication scheme to be through JWTBearer
    • This allowed me to accept a bearer token from Web App and now Web App to Api App authentication works as needed
  2. API App code changes

    • As API app was calling another downstream API App, I had to use AcquireTokenAsync passing in following details - ClientId, ClienCredentials and Access Token received from Web App earlier. This token is used to construct a UserAssertion

With the above changes call from Web App --> API App --> Downstream API App works fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM