AllowAnonymous doesn't work as expected in Web API - c#

In an ASP.NET CORE 3.1 Server-Side Blazor app, I am not able to get the AllowAnonymous working for a post type of request web API. The get requests do not have any issues.
Along with the solution for it work, please advise me about the needed security. Perhaps I lowered the security in my trials to get the post request work.
These 3 logs appear for every post request:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
....
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddDefaultUI()
.AddEntityFrameworkStores<EpisodeContext>();
services.AddMvc(options=> {
options.RespectBrowserAcceptHeader = true; })
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddRazorPages();
services.AddServerSideBlazor().AddCircuitOptions(option => { option.DetailedErrors = true; });
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<ApplicationUser>>();
services.AddHttpContextAccessor();
services.AddAuthorization(config =>
{
config.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.AddPolicy("RequireAdministratorRole",
policy => policy.RequireRole("admin"));
});
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
API Controller:
[AllowAnonymous]
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class DailyContentController : ControllerBase
{
[HttpPost("likeepisode"), AllowAnonymous]
public async Task<bool> LikeEpisode(string episodenumber)
{
bool result = await _CDService.LikeEpisode(episodenumber);
return result;
}
}
Plesk Hosting Settings:
Web Application Firewall

I have been able to stop the unintended redirect by setting the preferred domain to none in the hosting settings:

Related

Asp.Net Core API shuts down automatically when authorize is used

I have created an Asp.Net Web API for google authentication and here is my code in satrtup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = GoogleDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddGoogle(options =>
{
options.ClientId = "591241482908-66qgk38nbf1un6xxxxxxxxx.apps.googleusercontent.com";
options.ClientSecret = "GOCSPX-xxxxxxxxxxxxx";
});
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
And there is Login Controller
[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
[HttpGet("{id}")]
[Authorize]
public ActionResult<string> Get(int id)
{
return Ok(this.User);
}
}
Now the code builds successfully, but whenever I run the web API the console and the application shuts down automatically. How Can I solve this?

How to troubleshoot cors error on IIS server

I'm working on an application which the backend is a net core API with SignalR and the front end is Angular. Debugging on my computer it works as expected but when I publish on the server it shows Cors error even after enabling them on the startup.cs.
This is the error Im getting:
Access to XMLHttpRequest at 'http://server:10079/fareg/api/account' from origin 'http://server' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Can anyone please help to identify what I'm doing wrong to get ride of the CORS error?
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//add Windows authentication for http options request
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
services.AddDbContext<FAContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("FADB")));
services.AddCors(options =>
{
options.AddPolicy(name: _MyCors, builder =>
{
builder
.SetIsOriginAllowed(origin => new Uri(origin).Host == "server name")
//.WithOrigins("http://server/fareg", "http://localhost:4200")
.AllowCredentials()
.AllowAnyHeader()
//.SetIsOriginAllowed(_ => true)
.AllowAnyMethod();
});
});
services.AddSignalR().AddMessagePackProtocol();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(_MyCors);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseSignalR(routes =>
{
routes.MapHub<Hubs.HubFA>("/signalr");
});
app.UseMvc();
}
}
you put the UseCors() in a wrong place. Try to use this syntax
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy(_MyCors,
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
.....
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
.....
// app.UseRouting();
app.UseCors(_MyCors);
// app.UseAuthorization();
// app.UseEndpoints(..
}
Make sure that UseCors should be in the end of Configure method but before UseAuthorizaton. In your case it should be just above UseMvc(). But AddCors should be moved to the top of Configure services.
If this syntax is working for you, only after this you can try to add useorigin.

CORS not working in ASP.NET core Web API project

I built an ASP.NET core Web API (net core 3.1), and I try to enable CORS but it seems not working.
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowMyOrigin",
builder =>
{
builder.SetIsOriginAllowed(t => true)
.AllowCredentials();
});
});
...
}
‌
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("AllowMyOrigin");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseHttpsRedirection();
}
Controller:
[Route("api/[controller]")]
[ApiController]
public class airdata_updateController : ControllerBase
{
[EnableCors("AllowMyOrigin")]
[HttpGet]
public string test()
{
return "ok";
}
...
}
I use Postman test my API on local computer and it working well:
local computer
But I use Postman on other computer in the same LAN to call my API, it failed:
other computer
What should I do?
Try this:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddCors();
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseCors(
options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()
);
...
}
You won't need any decorators in your controller methods, the specified CORS policy ( AllowAnyOrigin, AllowAnyHeader, AllowAnyMethod) is applied in all of them. In order to customize the policy, check https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1
maybe this option can help you.
services.AddCors(options =>
{
options.AddPolicy("AllowMyOrigin",
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowAnyOrigin()
);
});

.Net Core 3.1 SPA authorize failed

I'm having issue to call authorize api from react SPA. It's working if removed the [Authorize] attribute in the controller/action, but once added in the attribute, the response goes to SPA home page.
Project Structure
IdentityServer (.net core 3.1 mvc with IdentityServer4 *reference token type)
Login (authentication with IdentityServer and auth callback to Portal)
Portal (.net core 3.1 react SPA, use IdentityServer4.AccessTokenValidation to validate
react
fetch('/api/test').then(async (response) => {
var data = await response.json();
console.dir(response);
console.dir(data);
});
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddControllersWithViews()
.ConfigureApiBehaviorOptions(options => { options.SuppressModelStateInvalidFilter = true; });
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://localhost:44302";
options.ApiName = "api1";
options.ApiSecret = "thisissecret";
});
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/build"; });
}
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); });
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (_WebHostEnvironment.IsDevelopment())
{
spa.UseReactDevelopmentServer("start");
}
});
}
Is worked if the api controller doesn't have the "Authorize" attribute, but once added in then will keep on unauthorized.
Sorry guys, is my mistake that I've missed to set the ApiSecret in IdentityServer. Therefore the it's keep on unauthenticated.
new ApiResource("api1", )
{
// the missing part
ApiSecrets = {
new Secret("thisissecret".Sha256())
}
}

Cross domain request in asp.net signalr core does not work?

I am working on asp.net core signalr 1.1.0 under asp.net core 2.2 version. I want to
make the cross-domain request for web client and as well as a mobile client.
When I send request from javascript client, then this request blocked, and below error shows,
(index):1 Access to XMLHttpRequest at 'https://localhost:44373/chatHub/negotiate?token=12' from origin 'https://localhost:44381' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
My Javascript client code
var connection = new signalR.HubConnectionBuilder().withUrl("https://localhost:44373/chatHub?token="+12).build();
Signalr core service startup class code
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()/*WithOrigins("https://localhost:44381")*/
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
//services.AddCors();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/chatHub");
});
//app.UseStaticFiles();
//app.UseCookiePolicy();
app.UseMvc();
}
builder.AllowAnyOrigin() its not working
builder => builder.WithOrigins("https://localhost:44381") its worked, but this is specific for this origin ,
I want to make AllowAnyOrigin()??
I got it working this way
On Configure services at the top
services.AddCors();
and in the Configure method
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.
public void ConfigureServices(IServiceCollection services)
{
services
.AddDbContext<ChatContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = 60000000;
});
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
services.AddMvcCore()
.AddAuthorization()
.AddJsonOptions(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
var identityServerAuthOptions = Configuration.GetSection("Identity").Get<IdentityServerAuthenticationOptions>();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = identityServerAuthOptions.Authority;
options.RequireHttpsMetadata = identityServerAuthOptions.RequireHttpsMetadata;
options.ApiName = identityServerAuthOptions.ApiName;
});
var settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.ContractResolver= new CamelCasePropertyNamesContractResolver();
services.AddSignalR()
.AddJsonProtocol(options => {
options.PayloadSerializerSettings = settings;
});
services.AddTransient<IUserService, UserService>();
services.AddCors();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
//Data.AddData(app.ApplicationServices.GetService<ChatContext>());
app.Use(async (context, next) =>
{
if (string.IsNullOrWhiteSpace(context.Request.Headers["Authorization"]))
{
if (context.Request.QueryString.HasValue)
{
var token = context.Request.QueryString.Value.Split('&').SingleOrDefault(x => x.Contains("authorization"))?.Split('=')[1];
if (!string.IsNullOrWhiteSpace(token))
{
context.Request.Headers.Add("Authorization", new[] { $"Bearer {token}" });
}
}
}
await next.Invoke();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseCors(x => x.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials());
app.UseSignalR(config =>
{
config.MapHub<UserHub>("/UsersHub");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
});
}
}
app.UseCors(builder =>
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
);
Whole code can be found here. This used to work just fine for me. I haven't opened it lately though
Github Repo
I see two issues with your code. Let's tackle them one by one.
Allowing all origins for the entire application even though you need it only for the SignalR connection. Consider the below code if you want to apply CORS policy only for the signalR endpoint
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<UsersHub>("/UsersHub")
.RequireCors((policyBuilder) => policyBuilder
.WithOrigins("clientUrls")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
});
It is recommended to not allow all origins but if you have such a use case then the below workaround can fix your problem. This is the trick of using .SetIsOriginAllowed(_ => true)
.SetIsOriginAllowed(_ => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
Further if you want more information, have a look at this guide for more details.

Categories

Resources