An example of policy-based authorization using Blazor.
Read the full blog post at https://chrissainty.com/securing-your-blazor-apps-configuring-policy-based-authorization-with-blazor/.
Companion code sample for my blog post - Configuring Policy-based Authorization with Blazor
License: MIT License
An example of policy-based authorization using Blazor.
Read the full blog post at https://chrissainty.com/securing-your-blazor-apps-configuring-policy-based-authorization-with-blazor/.
You MyCode is great, but I found in my testing to access roles using Azure and AzureAD that I had to modify the RequireClaim to look at the type "roles" to get the hit. Also, what was interesting in testing with IISExpress the roles never showed up in the Claims collection, so I just looked for my email address in preferred_username.
MyCode => Blazor server website using AzureAD authentication with roles defined in the clientID and setup in the enterprise clientID. Using microsoft.identity.web and .Net Core 5.0.
Gary
public class RoleLevel
{
public const string SUBMITTERS = "Submit";
public const string READERS = "Reader";
public const string CONFIGURERS = "Configure";
public const string ADMIN = "Admin";
}
services.AddMicrosoftIdentityWebAppAuthentication(Configuration);
bool isProduction = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Production";
bool isPPE = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "PPE";
services.AddAuthorization(options =>
{
if (isProduction || isPPE)
{
options.AddPolicy(RoleLevel.SUBMITTERS, policy => policy.RequireClaim("roles", RoleLevel.SUBMITTERS));
options.AddPolicy(RoleLevel.READERS, policy => policy.RequireClaim("roles", RoleLevel.READERS));
options.AddPolicy(RoleLevel.CONFIGURERS, policy => policy.RequireClaim("roles", RoleLevel.CONFIGURERS));
options.AddPolicy(RoleLevel.ADMIN, policy => policy.RequireClaim("roles", RoleLevel.ADMIN));
}
else
{
options.AddPolicy(RoleLevel.SUBMITTERS, policy => policy.RequireClaim("preferred_username", "[email protected]"));
options.AddPolicy(RoleLevel.READERS, policy => policy.RequireClaim("preferred_username", "[email protected]"));
options.AddPolicy(RoleLevel.CONFIGURERS, policy => policy.RequireClaim("preferred_username", "[email protected]"));
options.AddPolicy(RoleLevel.ADMIN, policy => policy.RequireClaim("preferred_username", "[email protected]"));
}
});
It appears that the server side state provider in your repo is basically the same implementation as the provider in core library
Is there any general reason that normal auth scenarios would need to re-implement this provider?
Guessing this is a Blazor-wide thing, but I can't get policies to work at all in the Navbar.razor.
Roles working just fine...
Any insight would be really handy,
Cheers,
T
Maybe i'm wrong, but it looks like that you call your authorization service
each time a AuthorizeView is displayed?
From your ApiAuthenticationStateProvider imlementation:
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var savedToken = await _localStorage.GetItemAsync<string>("authToken");
if (string.IsNullOrWhiteSpace(savedToken))
{
return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
}
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", savedToken);
var userInfo = await _httpClient.GetJsonAsync<UserModel>("api/accounts/user");
var identity = userInfo.IsAuthenticated ? new ClaimsIdentity(ParseClaimsFromJwt(savedToken), "jwt") : new ClaimsIdentity();
return new AuthenticationState(new ClaimsPrincipal(identity));
}
There is no check if the user is currently authorized, something like (pseudo code):
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
ClaimsIdentity identity;
if(IsAuthenticating)
{
return null; // pending
}
else if(IsAuthenticated)
{
// parse claims from token
}
else
{
// return default identity
}
return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(identity)));
}
Is there any reason for it? I think it brakes the jwt concept
Or in other words, handling token revokations in this way
is probably worse-rated than using sessions.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.