Blazor WebAssembly Cors Error if status is 401

Angelo 25 Reputation points
2023-02-11T14:44:09.0666667+00:00
I have a WebAssembly blazor application and a web service api with a method protected by the [Authorize] tag. If I call the method from PostMan it returns the 401 status correctly but if I call the same method from the Blazor application it goes into an exception and I can't capture the status, if I add the authorization token everything works. the question is:

why does it work with Postman and not with WebAssembly?

how to catch api call 401 status without it going into error?

Here is the Web API service side code configurations:

    app.UseCors(cors => cors
    .AllowAnyMethod()
    .AllowAnyHeader()
    .AllowAnyOrigin()
    );

And Controllers:

    [HttpGet("GetBooks")]
    [Authorize]
    public IEnumerable<string> GetBooks()
    {
         return new string[] { "Get", "MS1Controller" };
    }

This is the call from the Blazor application:

        try
        {
           HttpResponseMessage res = await _client.GetAsync("https://localhost:9004/api/MS1/GetBooks");
        }
        catch (Exception ex)
        {
          //from ex exception
          //if I don't enter the authentication token it goes into exception
          //System.Net.Http.HttpRequestException
          //TypeError: Failed to fetch

          //from F12 browser client side
         // Access to fetch at 'https://localhost:9004/api/MS1/GetBooks' from origin 'https://localhost:9006' 
         // has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is 
         //present on the requested resource.If an opaque response serves your needs, set the 
         //request's mode to 'no - cors' to fetch the resource with CORS disabled.
    
        }

NOTE: everything works fine if I send the authorization token on the call
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,596 questions
{count} vote

Accepted answer
  1. Xiaotian Yang-MSFT 85 Reputation points
    2023-02-13T07:06:52.01+00:00

    I edited my answer to make it easier to understand, here is the code of blazor application:

        private const string ServiceEndpoint = "https://localhost:7069/WeatherForecast";
    
        private string a = "init";
    
        private HttpResponseMessage res;
    
        protected override async Task OnInitializedAsync() => await GetTodoItems();
    
        private async Task GetTodoItems(){
            try
            {
                var requestMessage = new HttpRequestMessage()
                    {
                        Method = new HttpMethod("Get"),
                        RequestUri = new Uri(ServiceEndpoint),
                    };
    
                var response = await Http.SendAsync(requestMessage);
                var responseStatusCode = response.StatusCode;
    
                if (responseStatusCode == HttpStatusCode.Unauthorized)
                {
                    a = "1";
                }
                else if (response.IsSuccessStatusCode)
                {
                    a = "2";
                }
                else if (responseStatusCode == HttpStatusCode.InternalServerError)
                {
                    a = "4";
                }
                else
                {
                    a = "3";
                }
            } catch (Exception e)
            {
                a = "5";
            }
            
        }
    
    

    So the usage of these codes is checking if it successfully catches the target status code from the API, it will run into the target loop and test to see if it will run into the exception. Here is my test result screenshot:

    User's image

    You can see from the screenshot, I made several breakpoints to test it and blazor application successfully caught the status code, then it run into the target loop. So it can work too about the status code 401. Know we continue running the program to check whether it will go to the exception:

    User's image

    You can see from the screenshot, it didn't go into exception.

    -

    Update:

    I have checked the sample you uploaded, I made two changes and it works:

    Step A:

    Change the code in Program.cs file of API Project:

    app.UseCors(cors => cors
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowAnyOrigin()
                );
    
    

    before the app.UseAuthorization();

    Step B:

    I checked the sample, which seems it didn't add the 'if' loop code. The loop is the key to catch the 401 status code, you can do the next step when catch the 401 status code. For example, here is the code I added to the blazor client:

    try{
        var requestMessage = new HttpRequestMessage()
        {
            Method = new HttpMethod("Get"),
            RequestUri = new Uri("https://localhost:7291/WeatherForecast"),
        };
    
        var response = await Http.SendAsync(requestMessage);
        var responseStatusCode = response.StatusCode;
        if (responseStatusCode == HttpStatusCode.Unauthorized)
        { 
            a = "Permission Denied";
        }
        else if (response.IsSuccessStatusCode)
        {
            a = "2";
        }
        else if (responseStatusCode == HttpStatusCode.InternalServerError)
        { 
            a = "4";
        }
        else
        {
            a = "3";
        }
    }
    catch (Exception ex)
            {
                throw;
            }
    
    

    According to the loop code I added, if it successfully catch the 401 status code, it will show the access denied message. I added a breakpoint to test it and here is my test result:

    User's image

    You can see it successfully enter the loop, you can change the code to the action you want. In that case, blazor will not enter the exception.

    Here is the blazor web site of the testing result:

    User's image


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Best regards,

    Xiaotian

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 66,621 Reputation points
    2023-02-11T17:22:03.01+00:00

    With postman does the 401 response have the required CORS headers?

    note: Postman does not require CORS.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.