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 .