I want the user to access the Privacy page only if logged in, but the authorization only works if I log in into an account and log out, it does not work when I run the webapp at first and try to enter the privacy page I must login then logout for authorization to work. I am pretty sure everything was fine few hours ago, so here is some relevant code:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
//db
services.AddDbContext<TheAppContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Myconnection")));
//auth w/ cookies
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "MySessionCookie";
options.LoginPath = "/LogUsers/Expired";
options.SlidingExpiration = true;
});
//service 3/default
services.AddControllersWithViews();
}
// 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("/Home/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.UseAuthentication();
app.UseRouting();
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always,
Secure = CookieSecurePolicy.None,
};
app.UseCookiePolicy(cookiePolicyOptions);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
Methods of the relevant controller
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Login(Users login) //login users
{
if(IsValidUser(login.Username, login.Password))
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, login.Username),
new Claim(ClaimTypes.Role, "User"),
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
//The time at which the authentication ticket expires.
//ExpiresUtc = DateTime.Now.AddMinutes(60),
};
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
DisplayedUsername = "@" + login.Username;
CanUserLogout = 1;
return RedirectToAction("Index", "Home");
}
else
{
ViewBag.message = "Failed to login";
return View();
}
}
private bool IsValidUser(string username, string password)
{
var user = _context.Users.FirstOrDefault(u => u.Username == username && u.Password == password);
if (user != null)
{
return true;
}
return false;
}
[Authorize]
public async Task<ActionResult> Logout()
{
await HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
CanUserLogout = 0;
return RedirectToAction("Login", "Logusers");
}
Privacy action method from the home controller:
[Authorize]
public IActionResult Privacy()
{
return View();
}
Any help will be appreciated.
EDIT - 1
Startup.cs
updated
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)
{
//db
services.AddDbContext<TheAppContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Myconnection")));
//auth w/ cookies
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "MySessionCookie";
options.LoginPath = "/LogUsers/Expired";
options.SlidingExpiration = true;
});
//service 3/default
services.AddControllersWithViews();
}
// 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("/Home/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();
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always,
Secure = CookieSecurePolicy.None,
};
app.UseCookiePolicy(cookiePolicyOptions);
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
I don't see you calling the ConfigureServices() method, make sure you do that.
And secondly, you might need to move the call to app.UseCookiePolicy() to before app.UseAuthentication(). The order in which you do the initialization matters.
About the ConfigureServices call, I expected to see something like this in your code:
var builder = Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder(args);
ConfigureServices(builder.Services);
var app = builder.Build();
// All the app.UseBla() follows below.