0

we are authenticating an web API using azure ad JWT token which is deployed on separate server from UI server. In local environment it is working fine. but on server when we request for API call from UI server using azure ad bearer token, API throws error. we are getting error like : 401 (Unauthorized), we logged the stack trace also like below

token validation start at:- 7/20/2022 1:37:14 PM

token validation failed: System.Threading.Tasks.TaskCanceledException: A task was canceled. stack trace: at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) at Microsoft.Owin.Security.ActiveDirectory.WsFedMetadataRetriever.GetSigningKeys(String metadataEndpoint, TimeSpan backchannelTimeout, HttpMessageHandler backchannelHttpHandler) at Microsoft.Owin.Security.ActiveDirectory.WsFedCachingSecurityKeyProvider.RetrieveMetadata() at Microsoft.Owin.Security.ActiveDirectory.WsFedCachingSecurityKeyProvider..ctor(String metadataEndpoint, ICertificateValidator backchannelCertificateValidator, TimeSpan backchannelTimeout, HttpMessageHandler backchannelHttpHandler) at Owin.WindowsAzureActiveDirectoryBearerAuthenticationExtensions.UseWindowsAzureActiveDirectoryBearerAuthentication(IAppBuilder app, WindowsAzureActiveDirectoryBearerAuthenticationOptions options) at KFF.Web.App_Start.Startup.Configuration(IAppBuilder app) in D:\Source Code\KONE Maintence\maintenance\KFF\BackEnd\WebApp\App_Start\Startup.cs:line 132 massage : One or more errors occurred.

Below is my code which I used to authenticate the user: try {

            //used to validate azure ad bearer token

            sb.Append("token validation start at:-  " + DateTime.Now.ToString() + "  \n");
            app.UseWindowsAzureActiveDirectoryBearerAuthentication(
        new WindowsAzureActiveDirectoryBearerAuthenticationOptions
        {
            Tenant = tenant,

            TokenValidationParameters = new TokenValidationParameters
            {
                
                ValidAudience = ValidAudiences,
                ValidateIssuer = false,
                //  ValidIssuers = new[] { ValidIssuers }
                //IssuerSigningKeys = openidConfiguration.SigningKeys,
                //ValidateAudience = false
        }
        });



            sb.Append("\n" + "token validation success:-  " + DateTime.Now.ToString() + "\n" );
            File.AppendAllText(logPath + "log.txt", sb.ToString());
            sb.Clear();
        }
        catch (Exception ex)
        {
            sb.Append("\n" +  "token validation failed: " + "\n" + ex.InnerException + "\n" + " stack trace: "+ "\n" + ex.StackTrace + "\n" + "massage :" + "\n" + ex.Message);
            File.AppendAllText(logPath + "log.txt", sb.ToString());
            sb.Clear();
        } 
     

API controller code is mentioned below having Authorize attribute.

[Authorize]
public class AuthorizationController : ApiController
{    
    /// <summary>



    /// </summary>
    [Route("")]
        [HttpGet, HttpOptions]

        public string GetToken(bool staylogged, bool useSalesforce = false)
        {
            var authHeader = HttpContext.Current.Request.Headers["Authorization"];

            if (useSalesforce)
                return AuthHelper.SalesforceLogin(authHeader, staylogged);

            if (string.IsNullOrWhiteSpace(authHeader))
            {
                HttpContext.Current.Response.StatusCode = 401;
                return null;
            }  
            var jwt = authHeader.Replace("Bearer ", string.Empty);
            //var token = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(jwt);
            //authHeader = authHeader.Replace("Bearer", string.Empty);
            return jwt;

        }

Could any one guide me pls ?

manoj kumar
  • 41
  • 1
  • 4

1 Answers1

0

-401 unauthorized error most commonly occurs when audience and clientId mismatch happens.They must be same.

  • It has it be either AppId or AppIdUri according to the client Id set for that application.
  • If you are not sure try with array of audiences in case of ValidAudiences i.e; AppId of your client App or AppIdUri.If api can be called from more than one app, then mention those 2 appIds in the array .

Ex:

TokenValidationParameters = new TokenValidationParameters
            {
                ValidAudiences = new [] { 
                 ConfigurationManager.AppSettings["ida:Audience"],//
                 "xxxxxx-xxxxx-xxxxx-xxxxxxxxx",
                 "xxxxxx-xxxxx-xxx-xxxxx-xxxx1" ,
                  <AppIdUri>

                 },
  • Or instead try changing clientId to api:// if it is already given as AppId or vice versa.
  • AlsoIf the scope is created in the portal buy exposing the api, make sure to give scopes api:///scope in the code. enter image description here

enter image description here

Also if the token you get has the issuer with v2 endpoint, make sure to make the accesstokenacceptedversion as 2 else it can be 1 or null.

enter image description here

Also please make sure order is correct as below in start up class.

app.UseAuthentication();
app.UseAuthorization();

Similar cases:

  1. 401 - Unauthorized · Issue· GitHub
  2. c# - Web API (.NET Framework) Azure AD Authentication always returns 401 Unauthorized - Stack Overflow

But task cancelled exceptions occurs when HTTP request is canceled for example user closes the page by mistake or suddenly.

In that case try to create a custom message handler to handle error according to c# - "Task was canceled" errors on Azure website - Stack Overflow

public class CancelledTaskBugWorkaroundMessageHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var response = await base.SendAsync(request, cancellationToken);

        // suppress response  when the cancellation token has fired
        if (cancellationToken.IsCancellationRequested)
        {
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }

        return response;
    }
}
kavyaS
  • 8,026
  • 1
  • 7
  • 19