Hi all, I have a problem with Authorization that just popped up. I need to have role based authorization so I did some searching and put things together. My app worked one day and did not the next. I'm not sure what changed, but I will paste some code if you are interested in helping me. The problem seems to be when I try to protect a page or controller using @attribute [Authorize(Roles="admin")] or [Authorize(Roles="admin")] respectively.
So I created a Blazor App, changed the Authentication to 'Individual User Accounts' and checked ASP.Net Core hosted.
At this point Roles will not work, I believe it has to do with the way the claims token are built. Research took me to updating the Services as follows:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddControllersWithViews();
services.AddRazorPages();
}
I also added a seed method so my admin account would always be available. I added a 'seed' class and I call it from Startup.Configure. Here is the Configure method:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseWebAssemblyDebugging();
}
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.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
//This is the Users and Roles Seed Class
new UAR(Configuration,userManager,roleManager);
}
Here is the Seed Class:
public class UAR
{
IConfiguration Configuration { get; set; }
public UAR(IConfiguration configuration, UserManager<ApplicationUser> userManger, RoleManager<IdentityRole> roleManager)
{
Configuration = configuration;
SeedRole(roleManager);
SeedUser(userManger);
}
private void SeedRole(RoleManager<IdentityRole> roleManager)
{
if(roleManager.FindByNameAsync("admin").Result == null)
{
IdentityRole role = new IdentityRole() { Name = "admin" };
roleManager.CreateAsync(role).Wait();
}
if (roleManager.FindByNameAsync("user").Result == null)
{
IdentityRole role = new IdentityRole() { Name = "user" };
roleManager.CreateAsync(role).Wait();
}
}
private void SeedUser(UserManager<ApplicationUser> userManger)
{
string adminName = "admin@AuthTest.com"; (Yes, these credential lines are just for testing convenience)
string pwd = "!Admin12345";
string roleName = "admin";
if (userManger.FindByNameAsync(adminName).Result==null)
{
ApplicationUser user = new ApplicationUser()
{
UserName = adminName,
Email = adminName,
EmailConfirmed = true
};
userManger.CreateAsync(user, pwd).Wait();
if (userManger.FindByNameAsync(adminName).Result!=null)
{
userManger.AddToRoleAsync(user, roleName).Wait();
}
}
}
}
So now when I run the app I have a user that can login. And in my DB, my dbo.AspNetUserRoles has the appropriate user/role link.
I change the WeatherForecastController.cs [Authorize] to [Authorize(Roles="admin")] and I change the FetchData.razor page @attribute[Authorize] to @attribute[Authorize(Roles="admin")]
Now when I login and go to the 'Fetch Data' page I get the message
'An unhandled error has occured.Reload'
and Google Developer tools shows a:
'Failed to load resource: the server responded with a status of 403() info: System.Net.Http.HttpClient.BlazorApp1.ServerAPI.ClientHandler[101]
Received HTTP response after 4140.665ms - Forbidden
Any clues? I do not know what to change to make roles work, I suspect it is a claims failure. But it appeared to work for a while before it broke.
Thanks