I've been trying to create a SPA web application using React with ASP .NET Core 3.1 as backend, and now I need to restrict users going to certain pages. I know that for API methods I can do the following:
[Authorize(Roles="admin")]
[HttpGet]
public async Task<Whatever> Get(){ ... }
But that would only block users from using the API methods, which is good, but I also want to not let them go into the pages themselves.
Since I do not want to use their Blazor pages (because it breaks the separation of the client app and the backend), I cannot scaffold their login page, so I created mine using React and then implemented login and logout methods, which work, since when I'm logged in, the AspNetCore.Identity.Application cookie appears.
In order to do this, I added the following lines to Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddIdentityCore<ApplicationUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddSignInManager()
.AddDefaultTokenProviders();
services.AddAuthentication (o =>
{
o.DefaultScheme = IdentityConstants.ApplicationScheme;
o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
}).AddIdentityCookies(o => {});
...
}
public void Configure(IApplicationBuilder app)
{
...
app.UseAuthentication();
app.UseAuthorization();
...
}
Now I've read (source: https://stackoverflow.com/a/40055744/14806778) that, in React, you can define an onEnter method and check authentication there. So, to check if user is logged in or not, I implemented the simple method:
public bool IsUserLoggedIn()
{
return User.Identity.IsAuthenticated;
}
This also works, so I guess I could call this method in the onEnter method of React routing. I don't know if that's efficient or not, though.
Last, to check if user is in role, I could do something like this:
public async Task<bool> IsUserInRole(string requiredRole)
{
if(User.Identity.IsAuthenticated)
{
var user = await _userManager.GetUserAsync(User);
return await _userManager.IsInRoleAsync(user, requiredRole);
}
return false;
}
And call this onEnter instead.
My question is, is this approach valid? Is it safe? Does it have a huge performance impact? What are the alternatives? I've looked around a bit but I haven't seen a lot. I've read about JWT but I don't know how is it so different to this.
Also, I don't need Google/Apple/Facebook login, this is for an app which will be most likely running on localhost inside a VPN. I am using .NET Core 3.1, React 16.14 and React router dom 5.2.0.
Thank you.