Blazor Request blocked by CORS policy - .net-core

I am trying to send a request from a Blazor(client-side) client to a server and i keep getting this error:
Access to fetch at '[route]' (redirected from '[other route]') from
origin '[origin route]' 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.
On the server i have already added the CORS extension in the pipeline to no avail:
Server Startup
public void ConfigureServices(IServiceCollection services) {
services.AddCors();
services.AddResponseCompression(options => {
options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[]
{
MediaTypeNames.Application.Octet,
WasmMediaTypeNames.Application.Wasm,
});
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
app.UseResponseCompression();
app.UseMvc();
app.UseBlazor<Client.Startup>();
}
Blazor Client request
public async Task<Catalog> GetCatalogAsync() {
try {
HttpRequestMessage message = new HttpRequestMessage {
RequestUri = new Uri(BASE_PATH + Routes.GET_CATALOG), //BASE_PATH= 172.XX.XX.XX:8600
Method = HttpMethod.Get
};
var resp = await this.client.SendAsync(message); // client is HttpClient
var resultString = await resp.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<Catalog>(resultString);
return data;
} catch (Exception ex) {
throw;
}
}
Controller
[HttpGet]
[Route(Routes.GET_CATALOG)]
public async Task<Catalog> GetCatalogAsync() {
try {
var registry = await this.adminService.GetCatalogAsync();
return registry;
} catch (Exception ex) {
throw;
}
}
POCO
[Serializeable]
public struct Catalog{
}
What else can i do to be able to reach my server? Is it due to Blazor ?
As you can see i have already added the UseCors(...).
P.S
I have published my Blazor Server project together with the Client.They are in the same directory.This folder i placed it on a computer,and i am trying from my computer to open blazor : 172.168.18.22:8600/
Update
I have also tried adding headers to my HttpRequestMessage to no avail:
HttpRequestMessage message = new HttpRequestMessage {
RequestUri = new Uri(BASE_PATH + Routes.GET_CATALOG),
Method = HttpMethod.Get,
};
message.Headers.Add("Access-Control-Allow-Origin","*");
message.Headers.Add("Access-Control-Allow-Credentials", "true");
message.Headers.Add("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Content-Type");

#Bercovici Adrian, why do you add CORS support to your App ? Do you make cross origin requests ? If you don't, don't try to solve the issue by adding unnecessary configuration that may lead to more subtle bugs.
As usual, without seeing a repo of this app, can't help you any further.
Update:
What is this UseBlazor ?
You should upgrade your app to the latest version...
New Update:
Sorry, but I'm using the current preview version of Blazor
Startup class
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson();
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBlazorDebugging();
}
**// Instead of UseBlazor**
app.UseClientSideBlazorFiles<Client.Startup>();
app.UseStaticFiles();
app.UseRouting();
**// This configure your end points**
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
});
}
}
Note that I've removed the configuration of CORS as your client and server share the same domain. Please use the docs how to configure CORS appropriately.
Try this and see if it is working for you (I guess your issue is related to the configuration of the endpoints. Somehow, it seems to me that because you did not configure the endpoints, your request is redirected, and thus you get the message displayed by you above.)
Next to do is to check if your http request was appropriately cooked. But first checks the end points.

Somehow the problem was due to a very old client version that was cached on the browser.Never again will i forget to clear the browser cache after this problem.
Thank you all for your help and support !

Check that you do not send HTTP requests when running from HTTPS. For example if you send requests to http://172.168.18.22:8600 when your application was opened in https://172.168.18.22:8600 you may have an issue.

you need to specify your policy name in the middleware.
builder.Services.AddCors(policy =>{
policy.AddPolicy("Policy_Name", builder =>
builder.WithOrigins("https://*:5001/")
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyOrigin()
);});
// Configure the HTTP request pipeline.
app.UseCors("Policy_Name");

Related

CORS policy issue when consuming ASP NET Core 3.1 Web Api by Angular 8

I have encountered issue with CORS policy when developing Angular 8, ASP NET Core Web Api web application. My angular app is running on http://localhost:4200
There is one service created for communication with Web Api. It looks as follows
#Injectable({
providedIn: 'root'
})
export class AuthenticationService {
apiUrl: string = "";
constructor(private http: HttpClient) {
this.apiUrl = 'https://localhost:44316';
}
login(Username: any, Password: any){
return this.http.post<Observable<ResultItem<AuthenticationResponse>>>(this.apiUrl + "/api/User/Authenticate", {Username: Username, Password: Password});
}
}
Services is later called within component, but it is simply injected, and used with subscribe method.
onLogin(){
this.authenticationService.login(this.loginFormValues.username.value, this.loginFormValues.password.value).subscribe(
result => {});
}
Web Api is running seperatly, on https://localhost:44316/
End point for the method called from Angular looks as follows:
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly IUserService userService;
public UserController(IUserService userService)
{
this.userService = userService;
}
[HttpPost("Authenticate")]
public async Task<IActionResult> Authenticate(AuthenticationModel model)
{
return Ok(await userService.Login(model));
}
}
What I am most concerned about is my Startup file. So far, I have tried to change the CORS setting there, but with no successful results. Code of the Startup.cs file looks as follows.
Quick note:
Two lines of code within ConfigureServices method use some of my external functions, and their purpose is to:
AddSubstracture: registers all repositories as transients and registers DbContext.
AddApplication: registers services which are one layer above repositories as transients
Startup.cs code looks as follows
public class Startup
{
private IServiceCollection _services;
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
Configuration = configuration;
Environment = environment;
SportFacilityUnitSettings = configuration.Get<SportFacilityUnitSettings>();
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; }
public SportFacilityUnitSettings SportFacilityUnitSettings { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddMvc(option => option.EnableEndpointRouting = false);
services.AddSubstructure(Configuration, Environment, SportFacilityUnitSettings);
services.AddApplication();
services.AddScoped<IPasswordHasher<User>, PasswordHasher<User>>();
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddControllers().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddHttpContextAccessor();
_services = services;
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors(
options => options.SetIsOriginAllowed(x => _ = true).AllowAnyMethod().AllowAnyHeader().AllowCredentials()
);
app.UseMvc();
app.UseHsts();
app.UseMiddleware<JwtMiddleware>();
app.UseAuthentication();
app.UseRouting();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
When I hit the login button, which purpose is to send the request, I receive following error in web browser console.
Access to XMLHttpRequest at 'https://localhost:44316/api/User/Authenticate' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The weirdest thing about it, is when I debug it, and set up a breakpoint in Api layer, debugger hits it, then it enters the service layer and fails somewhere inside Authentication method .
Go to IIS where your application is hosted and check if you have set the below information right.
#Step 1 : IIS --> HTTP Response header]
#Step 2 : : Setting 4 fields in your API app hosted under IIS
#Step 3: If the above 2 steps does not work, make sure you follow the msdn information to enable cors for your application
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1
Step 4 : : Investigate the header information you are using in your web API and if that's allowed under your IIS setting (as mentioned in Step 1)
Step 5 : : Place a breakpoint in your authenticate method to see where and why its failing. You may get more clue from this error information as well.
Step 6 : Try enabling CrossDomain to true from your front end.
Step 7 : Try enabling https for both the application (calling application and called application)

SignalR gives 404 when using WebSockets or ServerSentEvents for some users but not for others

SignalR gives me 404 when trying to connect for some users. URLs are the same except for access_token.
It is stable reproducible per user (I mean that some users are stable OK, some users are stable 404).
access_token parsed jwt diff (left is OK user, right gets 404):
I did a trace level of logs and have next:
For the OK user:
For the user that gets 404:
Note: URLs under black squares are the same.
Front End is Angular 9 with package "#microsoft/signalr": "^3.1.8", and here's the code that builds the connection:
private buildHub(): HubConnection {
console.log(this.authService.accessToken);
let builder = new HubConnectionBuilder()
.withAutomaticReconnect()
.configureLogging(LogLevel.Information)
.withUrl('ws/notificationHub', {
accessTokenFactory: () => this.authService.accessToken
});
if (this.debugMode) {
builder = builder.configureLogging(LogLevel.Trace);
}
return builder.build();
}
Backend is using next code in Startup for configuring signalR hub:
In public void ConfigureServices(IServiceCollection services):
services.AddSignalR()
.AddJsonProtocol(options =>
{
options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
});
In public void Configure(IApplicationBuilder app, IHostingEnvironment env):
app.UseSignalR(route =>
{
route.MapHub<NotificationHub>("/ws/notificationHub");
});
Also we use custom authentication, so we have Authorize attribute for the Hub class:
[Authorize]
public class NotificationHub: Hub<INotificationHubClient>
and this code in public void ConfigureServices(IServiceCollection services):
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = identityServerSettings.Url;
options.Audience = identityServerSettings.ApiScopeName;
options.RequireHttpsMetadata = identityServerSettings.RequireHttpsMetadata;
options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/ws"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
Unfortunately, I don't have the full access to the environment where it is reproducible, but I can request to see any settings or try to make some changes.
What else can I try to troubleshoot the issue?
UPDATE: negotiate is fine for both users.
I had this issue recently, after the size of my JWT increased. I found that in my case the 404 error was being thrown by IIS because the query string exceeded the limit of 2048. After increasing the query string max length, my issue was resolved.

OpenIddict - hosting auth server and web api resource in same project

I want to implement an OpenIdConnect/Oauth2 server using OpenIddict in order to secure a .NET core API app. Most examples I have seen implement these as separate projects.
The client app is a SPA and we are using implicit flow.
I have based my solution on the code shown in the OpenIddict samples here:
https://github.com/openiddict/openiddict-samples
For the project I am working on it would ideally have the Auth server and API to use the same port and be in the same project. ( One of the customer's requirements is that they don't want another server to configure since they own the API resource and it will be on the same server)
I have configured OpenIddict and combined it with our API project. Almost everything works correctly - the API endpoints are protected with the [Authorize] attribute and prevent access to protected API end points. However, when the API resource is protected, instead of returning a 401 Unauthorized HTTP status code, the returned result is the HTML Login page of the Auth server itself.
Here is the relevant setup code in my Startup.cs file:
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseApplicationInsightsRequestTelemetry();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseApplicationInsightsExceptionTelemetry();
app.UseStaticFiles();
app.UseIdentity();
app.UseCors("AllowAll");
//app.UseCors(builder =>
//{
// builder.AllowAnyOrigin();//)WithOrigins("http://localhost:9000");
// builder.WithMethods("GET","POST", "PUT", "DELETE", "OPTIONS");
// builder.WithHeaders("Authorization");
//});
app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api"), branch =>
{
branch.UseIdentity();
});
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), branch =>
{
branch.UseOAuthValidation();
});
app.UseOpenIddict();
#region Adding resource config here (api)
// Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
app.UseOAuthIntrospection(options =>
{
options.AutomaticAuthenticate = true;
options.AutomaticChallenge = true;
options.Authority = "http://localhost:5000";
options.Audiences.Add("resource-server-1");
options.ClientId = "resource-server-1";
options.ClientSecret = "846B62D0-DEF9-4215-A99D-86E6B8DAB342";
});
//app.UseCors(builder => {
// builder.WithOrigins("http://localhost:9000");
// builder.WithMethods("GET");
// builder.WithHeaders("Authorization");
//});
#endregion
app.UseMvcWithDefaultRoute();
// Seed the database with the sample applications.
// Note: in a real world application, this step should be part of a setup script.
InitializeAsync(app.ApplicationServices, CancellationToken.None).GetAwaiter().GetResult();
}
private async Task InitializeAsync(IServiceProvider services, CancellationToken cancellationToken)
{
// Create a new service scope to ensure the database context is correctly disposed when this methods returns.
using (var scope = services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
//await context.Database.EnsureCreatedAsync();
var manager = scope.ServiceProvider.GetRequiredService<OpenIddictApplicationManager<OpenIddictApplication>>();
if (await manager.FindByClientIdAsync("MySPA", cancellationToken) == null)
{
var application = new OpenIddictApplication
{
ClientId = "MySPA",
DisplayName = "MySPA",
LogoutRedirectUri = "http://localhost:9000/signout-oidc",
RedirectUri = "http://localhost:9000/signin-oidc"
};
await manager.CreateAsync(application, cancellationToken);
}
if (await manager.FindByClientIdAsync("resource-server-1", cancellationToken) == null)
{
var application = new OpenIddictApplication
{
ClientId = "resource-server-1"
};
await manager.CreateAsync(application, "846B62D0-DEF9-4215-A99D-86E6B8DAB342", cancellationToken);
}
}
}
Not sure how to implement these both side by side in the same project. As mentioned it all "works" except the API is returning the HTML login page and not a desired HTTP status
app.UseIdentity(); is present twice in your pipeline, which defeats the whole purpose of using branch.UseIdentity() in a app.UseWhen() branching builder (i.e making sure the cookies middleware registered by Identity are not invoked for your API endpoints).
Remove the first occurrence and it should work.
You set the AutomaticChallenge to true. According to the documentation
this flag indicates that the middleware should redirect the browser to the LoginPath or AccessDeniedPath when authorization fails.
So by setting this to false it will not redirect to the login.

How to pass header in Azure endpoint..?

I am using Azure API , URL getting below error please help on this issue. please share codesnip, how to change in web.config and endpoints.
The HTTP request is unauthorized with client authentication scheme
'Anonymous'. The authentication header received from the server was
'AzureApiManagementKey
realm="https:/azure.azure-api.net/MethodName",name="Ocp-Apim-Subscription-Key",type="header"'.
I know this is a very old question still, my answer would help someone faces the same issue.
The solution is to create a custom endpoint behavior where you add a custom message handler to the binding parameters.
In the custom message handler, please add your request headers. After this, use any of the binding technique (like basichttpsbinding or NetHttpsBinding) with security mode as "Transport" and MessageEncoding as "Text" for creating soap client object. Add custom endpoint behavior to the soap client.
public class CustomEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
bindingParameters.Add(new Func<HttpClientHandler, HttpMessageHandler>(x =>
{
return new CustomMessageHandler(x);
}));
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { }
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint endpoint) { }
}
public class CustomMessageHandler : DelegatingHandler
{
public CustomMessageHandler(HttpClientHandler handler)
{
InnerHandler = handler;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
request.Headers.Add("xxxx", "abcde");
return base.SendAsync(request, cancellationToken);
}
}
The console app to consume the service.
static async Task Main(string[] args)
{
var client = GetSOAPClient();
try
{
var result = await client.MyOperation().ConfigureAwait(false);
if(result.Body != null && result.Body.status == "Success")
{
Console.WriteLine(result.Body.myValue);
}
}
catch (Exception ex)
{
Console.WriteLine(ex?.Message);
}
Console.ReadKey();
}
static MyServiceClient GetSOAPClient()
{
NetHttpsBinding binding = new NetHttpsBinding();
binding.Security.Mode = BasicHttpsSecurityMode.Transport;
binding.MessageEncoding = NetHttpMessageEncoding.Text;
EndpointAddress ea = new EndpointAddress(new Uri("https://myazureurl"));
var client = new MyServiceClient(binding, ea);
client.Endpoint.EndpointBehaviors.Add(new CustomEndpointBehavior());
return client;
}
}
This is complaining that your Subscription key is wrong. If you check the response body, it will give you a readable message of what the real problem is. Double check you are entering the correct subscription key for your Azure API access.
You get your subscription key from the Developer Portal under your profile menu. You can see an example of the subscription key being used in this article under the section "Call an operation from the developer portal": https://learn.microsoft.com/en-us/azure/api-management/api-management-get-started
Also, the 'The HTTP request is unauthorized with client authentication scheme 'Anonymous'.' part of the message is a red herring and a separate problem with how responses work.

OWIN token authentication 400 Bad Request on OPTIONS from browser

I am using token authentication for small project based on this article: http://bitoftech.net/2014/06/09/angularjs-token-authentication-using-asp-net-web-api-2-owin-asp-net-identity/
Everything seems to work fine except one thing: OWIN based token authentication doesn't allow OPTIONS request on /token endpoint. Web API returns 400 Bad Request and whole browser app stops sending POST request to obtain token.
I have all CORS enabled in application as in sample project. Below some code that might be relevant:
public class Startup
{
public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
public void Configuration(IAppBuilder app)
{
AreaRegistration.RegisterAllAreas();
UnityConfig.RegisterComponents();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
HttpConfiguration config = new HttpConfiguration();
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
ConfigureOAuth(app);
WebApiConfig.Register(config);
app.UseWebApi(config);
Database.SetInitializer(new ApplicationContext.Initializer());
}
public void ConfigureOAuth(IAppBuilder app)
{
//use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalCookie);
OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60),
Provider = new SimpleAuthorizationServerProvider(),
RefreshTokenProvider = new SimpleRefreshTokenProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(OAuthBearerOptions);
}
}
Below is my login function from javascript (I am using angularjs for that purpose)
var _login = function (loginData) {
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
data = data + "&client_id=" + ngAuthSettings.clientId;
var deferred = $q.defer();
$http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {
localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: response.refresh_token, useRefreshTokens: true });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
_authentication.useRefreshTokens = loginData.useRefreshTokens;
deferred.resolve(response);
}).error(function (err, status) {
_logOut();
deferred.reject(err);
});
return deferred.promise;
};
var _logOut = function () {
localStorageService.remove('authorizationData');
_authentication.isAuth = false;
_authentication.userName = "";
_authentication.useRefreshTokens = false;
};
I've lost some time on this problem today. Finally i think i've found a solution.
Override method inside your OAuthAuthorizationServerProvider:
public override Task MatchEndpoint(OAuthMatchEndpointContext context)
{
if (context.IsTokenEndpoint && context.Request.Method == "OPTIONS")
{
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "authorization" });
context.RequestCompleted();
return Task.FromResult(0);
}
return base.MatchEndpoint(context);
}
This appears to do three necessary things:
Force auth server to respond to OPTIONS request with 200 (OK) HTTP status,
Allow request to come from anywhere by setting Access-Control-Allow-Origin
Allows Authorization header to be set on subsequent requests by setting Access-Control-Allow-Headers
After those steps angular finally behaves correctly when requesting token endpoint with OPTIONS method. OK status is returned and it repeats request with POST method to get full token data.
Override this method inside your OAuthAuthorizationServerProvider:
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
Are you running it locally or are you publishing it to Azure like in the blog article's sample code?
If you're running it on Azure, you can easily fix CORS problems by enabling CORS in the Azure portal:
Click on your App Service in the Azure Portal to enter the management screen.
In the list of management options, scroll down to the 'API' section, where you will find the 'CORS' option. (Alternatively type 'CORS' in the search box).
Enter the allowed origin, or enter '*' to enable all, and click save.
This fixed the OPTIONS preflight check problem for me, which a few other people seem to have had from the code in that particular blog article.
Solved it. The problem was not sending with OPTIONS request header Access-Control-Request-Method
This should do the trick:
app.UseCors(CorsOptions.AllowAll);

Resources