2

I have a ASP.NET Core Server running on local IP https://192.168.188.31:44302 with Web API Enpoints. I can connect to said server with VS Code REST Client. Now I want to conenct to the Web API with Blazor WebAssembly running on https://192.168.188.31:5555.

My Blozor Code:

@page "/login"
@inject HttpClient Http

[ ... some "HTML"-Code ... ]

@code {
    private async Task Authenticate()
    {
        var loginModel = new LoginModel
        {
            Mail = "some@mail.com",
            Password = "s3cr3T"
        };
        var requestMessage = new HttpRequestMessage()
        {
            Method = new HttpMethod("POST"),
            RequestUri = ClientB.Classes.Uris.AuthenticateUser(),
            Content =
                JsonContent.Create(loginModel)
        };

        var response = await Http.SendAsync(requestMessage);
        var responseStatusCode = response.StatusCode;

        var responseBody = await response.Content.ReadAsStringAsync();

        Console.WriteLine("responseBody: " + responseBody);
    }

    public async void LoginSubmit(EditContext editContext)
    {
        await Authenticate();
        Console.WriteLine("Debug: Valid Submit");
    }
}

When I now trigger LoginSubmit I get the following error-message in the developer console of Chrome and Firefox: login:1 Access to fetch at 'https://192.168.188.31:44302/user/authenticate' from origin 'https://192.168.188.31:5555' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.

I'm new to web development and found that you have to enable CORS on the server-side ASP.NET Core project, so I extended startup.cs with

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<UserDataContext, UserSqliteDataContext>();

services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("https://192.168.188.31:44302",
                "https://192.168.188.31:5555",
                "https://localhost:44302", 
                "https://localhost:5555")
            .AllowAnyHeader()
            .AllowAnyMethod();
        });
});

services.AddControllers();
services.AddApiVersioning(x =>
{
...
});

services.AddAuthentication(x =>
    ...
});
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

services.AddScoped<IViewerService, ViewerService>();
}

public void Configure(IApplicationBuilder app,
    IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    Program.IsDevelopment = env.IsDevelopment();

    app.UseHttpsRedirection();
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();
    app.UseCors(MyAllowSpecificOrigins);

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    Log.Initialize();
}

But I still get above error message. Am I doing something wrong with configuring CORS? Why is it working as expected with the VS Code REST Client and how am I making the call wrong in the Blazor WASM application?

user3079834
  • 1,461
  • 1
  • 21
  • 46

3 Answers3

4

The issue causing the error message login:1 Access to fetch at 'https://192.168.188.31:44302/user/authenticate' from origin 'https://192.168.188.31:5555' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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. was caused by HttpsRedirection.

To resolve the issue, either deactivate HttpsRedirection by removing the line app.UseHttpsRedirection(); in function Configure or add the proper ports for redirection in function ConfigureServices (recommended way).

In my case, I start my WebAPI at port 44302, so my solution looks like this (you have to adapt it to your port number):

if (Program.IsDevelopment)
{
    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
        options.HttpsPort = 44302;
    });
}
else
{
    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
        options.HttpsPort = 443;
    });
}

Also note that it is sufficient to add the IP address of the requesting API to CORS like this:

services.AddCors(options =>
{
    options.AddPolicy(name: specificOrigins,
        builder =>
        {
            builder.WithOrigins("https://192.168.188.31:5555",
                "http://192.168.188.31:5444")
            .AllowAnyHeader()
            .AllowAnyMethod();
        });
});
user3079834
  • 1,461
  • 1
  • 21
  • 46
2

Step 1: Please add following code in your WebAPI's Startup.cs to allow CORS with specific origins:

    services.AddCors(options =>
    {
        options.AddDefaultPolicy(builder =>
        builder.WithOrigins("https://localhost:44351")
        .AllowAnyHeader()
        .AllowAnyMethod());
    });

Step 2: Now change "https://localhost:44351" in above code with your blazor web assembly application's URL. Refer below screen shot:

enter image description here

Step 3: Now add app.UseCors() in your WebAPI's Configure method after app.UseRouting() and before app.UseRouting(). Please refer below screen shot:

enter image description here

I was also facing same issue and it solved my problem. Hope it will also work for you.

Note: No changes required in Blazor web assembly code to fix the above issue.

0

I'm not sure what the defaults are but try it with explicit settings:

options.AddPolicy(name: MyAllowSpecificOrigins,
    builder =>
    {
        builder.WithOrigins("https://192.168.188.31:44302", 
                   "https://192.168.188.31:55555", 
                   "https://localhost:44302", 
                   "https://localhost:55555")
                 .AllowAnyHeader()
                 .AllowAnyMethod();               
    });
Henk Holterman
  • 236,989
  • 28
  • 287
  • 464
  • I tried it, but still get the error message `login:1 Access to fetch at 'https://192.168.188.31:44302/user/authenticate' from origin 'https://192.168.188.31:5555' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.` – user3079834 Jul 14 '20 at 18:04
  • 1
    Yes, put the UseCors() before UseAuth*() – Henk Holterman Jul 14 '20 at 18:10
  • I put it below `UseRouting()`, still no change. Is there something else I can do? Maybe I'm doing something fundamentally wrong? – user3079834 Jul 14 '20 at 18:49
  • Ik looks largely Ok, I can't spot the error. Maybe it's that DIY HttpRequestMessage . Find a working sample and compare notes. – Henk Holterman Jul 15 '20 at 18:23
  • Okay I got a partial success, removing `app.UseHttpsRedirection()` from `Configure()` does the trick for Chrome. However in Firefox I still have an issue (even with setting CORS to `AllowAnyOrigin()` with the message `Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://192.168.188.31:44302/user/authenticate. (Reason: CORS request did not succeed).`. What can I do about that? – user3079834 Jul 15 '20 at 19:31
  • 1
    Update: That issue is because of a wrongly issued certificate (an IP address is **not** an alternative DNS name). Now everything works fine. – user3079834 Jul 15 '20 at 20:24
  • You can post a self-answer for this. – Henk Holterman Jul 16 '20 at 14:58