I am using Blazor server side and want to set Cookie for that i am using SignInAsync function of HttpContext but giving me this error "The response headers cannot be modified because the response has already started".
The error flashes when it comes to the following line
await httpContextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
I have tried every this but still facing the error
My Startup.cs Page
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using power_SLIC.Data;
using System.Net.Http;
using power_SLIC.Services;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace power_SLIC
{
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.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
// services.AddProtectedBrowserStorage();
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options => {
options.LoginPath = "/";
});
//.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, act => {
// act.LoginPath = "/";
// act.AccessDeniedPath = "/";
// act.SlidingExpiration = true;
//}
// services.AddHttpClient();
services.AddSingleton<HttpClient>();
// services.AddScoped<AuthenticationStateProvider, TokenAuthenticationServices>();
//services.AddScoped<ILoginservices, TokenAuthenticationServices>();
/// services.AddSingleton<HttpClient>();
services.AddAuthorization(option =>
{
option.AddPolicy("Employee", policy => policy.RequireClaim("IsUserEmployee", "true"));
});
}
// 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();
}
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.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
}
And My Razor Page looks like this Loginscreen.razor
@layout LoginLayout
@page "/"
@using System.Threading.Tasks
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Authentication.Cookies
@using Microsoft.AspNetCore.Http
@using Microsoft.AspNetCore.Mvc
@using Newtonsoft.Json
@using System.Text
@using Newtonsoft.Json.Linq
@using Microsoft.AspNetCore.ProtectedBrowserStorage
@using System.Security.Claims
@using System.Web
@*@inject ProtectedSessionStorage ProtectedSessionStore*@
@inject IJSRuntime JsRuntime;
@inject NavigationManager NavigationManager
@inject HttpClient http
@inject IHttpContextAccessor httpContextAccessor
<div style="margin-left:39%;margin-right:17%">
<div class="card">
<h4 class="card-header">Login</h4>
<div class="card-body">
<EditForm Model="@model" >
@*<DataAnnotationsValidator />*@
<div class="form-group">
<label>Username</label>
<InputText @bind-Value="model.SSam_User" class="form-control" />
@*<ValidationMessage For="@(() => model.Username)" />*@
</div>
<div class="form-group">
<label>Password</label>
<InputText @bind-Value="model.SSam_Pwd" type="password" class="form-control" />
@*<ValidationMessage For="@(() => model.Password)" />*@
</div>
<button class="btn btn-primary" @onclick = "AddItem" >
Login
</button>
@* <NavLink href="account/register" @onClick = "window.location.href = 'home'" class="btn btn-link">Register</NavLink>*@
</EditForm>
</div>
</div>
</div>
@code{
private bool isConnected = false;
private Model.LoginModel model = new Model.LoginModel();
class Values
{
public string result {get; set;}
}
class Result{
public List<Values> result { get; set;}
};
public async void AddItem()
{
var addItem = new Model.LoginModel {SSam_User=model.SSam_User,SSam_Pwd=model.SSam_Pwd, UnitSname = "HFHO" };
string output = JsonConvert.SerializeObject(addItem);
var Stringcontent = new StringContent(output,Encoding.UTF8,"application/json");
var op = await http.PostAsync("https://localhost:44392/api/outputs/getpowerbi_token", Stringcontent);
var resultcontent = op.Content.ReadAsStringAsync().Result;
dynamic oit = JsonConvert.DeserializeObject<dynamic>(resultcontent);
var accesstoken = oit["result"]["Token_status"].Value;
var op1 = oit["result"]["login_response"][0]["status"].Value;
if(op1 == "success")
{
var reo = httpContextAccessor.HttpContext.Request.Headers;
var prerender = !httpContextAccessor.HttpContext.Response.HasStarted;
if (!httpContextAccessor.HttpContext.Request.Headers.ContainsKey("Header"))
{
if (!httpContextAccessor.HttpContext.Response.HasStarted)
{
string result;
httpContextAccessor.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
result = JsonConvert.SerializeObject(new { error = "Request doesn't contains header" });
httpContextAccessor.HttpContext.Response.ContentType = "application/json";
await httpContextAccessor.HttpContext.Response.WriteAsync(result);
}
else
{
await httpContextAccessor.HttpContext.Response.HttpContext.Response.WriteAsync(string.Empty);
}
var reo1 = httpContextAccessor.HttpContext.Response.HttpContext.Response;
AuthenticateResult.Fail("request doesn't contains header");
}
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, model.SSam_User),
new Claim("Token", accesstoken),
new Claim(ClaimTypes.Role, "User"),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
IsPersistent = true,
RedirectUri = "/",
ExpiresUtc = DateTime.UtcNow.AddSeconds(30)
};
var j1 = CookieAuthenticationDefaults.AuthenticationScheme;
await httpContextAccessor.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
NavigationManager.NavigateTo("/powerbi",true);
}
}
}