I have a problem about api login with cookies, the goal is that before the user can call any api, the user must first call /api/Authentication/Login and then he can use the rest of the operations. However, when I call for example /api/Batch, instead of returning AccessDenied, I get the full html of the login page in the body of the response which is wrong in this case.
services.AddScoped<IAuthenticationService, LdapAuthenticationService>();
services.AddHttpContextAccessor();
services.AddIdentity<User, Role>(o => {
o.Password.RequireNonAlphanumeric = false;
o.Password.RequiredLength = 8;
o.Password.RequireLowercase = true;
o.Password.RequireDigit = true;
o.Password.RequireUppercase = true;
}).AddEntityFrameworkStores<ScanLinkContext>().AddDefaultTokenProviders().AddRoles<Role>();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/SignIn";
});
services
.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = ".AspNetCore.Cookies";
options.Cookie.HttpOnly = true;
options.LoginPath = "/Account/SignIn"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
options.LogoutPath = "/Account/SignOut"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = "/Account/SignIn"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = true;
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
});
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WEBAPI v1"));
}
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.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseStatusCodePagesWithRedirects("/Errors/{0}");
app.UseRouting();
// Add authentication to request pipeline
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
I need to leave the original configuration, so that it is functional for the web and in the case of visiting a page to which the user has the right, it redirects him to the login page, but for the cookie I would need a different behavior as described above
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class BatchController : ControllerBase
{
private readonly ScanLinkContext _scanlinkContext;
public BatchController( ScanLinkContext scanLinkContext)
{
_scanlinkContext = scanLinkContext;
}
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
[Route("Import")]
[HttpPost]
public async Task<StatusCodeResult> PostImport([FromBody] string xml)
{
return Ok();
}
[HttpPut("[action]/{batchName}")]
public async Task<StatusCodeResult> Tranform(string batchName, [FromBody] string json)
{
return Ok();
}
[HttpPut("[action]/{batchName}")]
public async Task<StatusCodeResult> Validate(string batchName, [FromBody] string json)
{
return Ok();
}
[HttpPut("[action]/{batchName}")]
public async Task<StatusCodeResult> Unlock(string batchName)
{
return Ok();
}
[HttpDelete("{batchName}")]
public async Task<StatusCodeResult> Delete(string batchName)
{
return Ok();
}
}
How should I adjust the configuration to achieve the goal?
CodePudding user response:
You have to override the Events.OnRedriectLogin like this.
.ConfigureApplicationCookie(options =>
{
//other options...
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
}