Comments (9)
Thank you for picking up on this bit of code. I’ll try and update the blog posts which reference it to reflect your suggested improvement. :)
from policybasedauthwithblazor.
@endeffects Sorry this has taken me so long but I've finally updated the article and the sample code to fix the issue you found.
from policybasedauthwithblazor.
Alternative implementation without hammering the auth service:
public class AuthStateProvider : AuthenticationStateProvider
{
private const string tokenKey = "authToken";
internal readonly IStorage storage;
public AuthStateProvider(IStorage storage)
{
this.storage = storage ?? throw new ArgumentNullException(nameof(storage));
}
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
{
var savedToken = await this.storage.GetItem<string>(tokenKey);
return string.IsNullOrWhiteSpace(savedToken) ? await CreateAnomymousState() : await CreateAuthenticatedState(savedToken);
}
public async Task MarkUserAsAuthenticated(string token)
{
await this.storage.SetItem(tokenKey, token);
base.NotifyAuthenticationStateChanged(CreateAuthenticatedState(token));
}
public async Task MarkUserAsLoggedOut()
{
await this.storage.RemoveItem(tokenKey);
base.NotifyAuthenticationStateChanged(CreateAnomymousState());
}
private static async Task<AuthenticationState> CreateAuthenticatedState(string token)
{
var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(ParseClaimsFromJwt(token), "jwt"));
return await Task.FromResult(new AuthenticationState(authenticatedUser));
}
private static async Task<AuthenticationState> CreateAnomymousState()
{
var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
return await Task.FromResult(new AuthenticationState(anonymousUser));
}
private static IEnumerable<Claim> ParseClaimsFromJwt(string jwt)
{
var result = new List<Claim>();
var payload = ParseBase64WithoutPadding(jwt.Split('.')[1]);
var claims = JsonConvert.DeserializeObject<Dictionary<string, object>>(payload);
claims.TryGetValue(ClaimTypes.Role, out var roles);
if (roles != null)
{
if (roles.ToString().Trim().StartsWith("["))
{
var parsedRoles = JsonConvert.DeserializeObject<string[]>(roles.ToString());
result.AddRange(parsedRoles.Select(parsedRole => new Claim(ClaimTypes.Role, parsedRole)));
}
else
{
result.Add(new Claim(ClaimTypes.Role, roles.ToString()));
}
claims.Remove(ClaimTypes.Role);
}
result.AddRange(claims.Select(e => new Claim(e.Key, e.Value.ToString())));
return result;
}
private static string ParseBase64WithoutPadding(string base64)
{
switch (base64.Length % 4)
{
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
return BitConverter.ToString(Convert.FromBase64String(base64));
}
}
from policybasedauthwithblazor.
You’re correct, the auth service is getting hit each time a AuthorizeView is displayed. The purpose of this code sample is to show policy based auth rather than best practice for token management.
I take your point that the code could definitely be improved but I’m not sure I would say it breaks the JWT concept. I have seen plenty of applications which do checks on the validity of a token before firing the main request.
Ultimately, I think an access token and refresh token approach is probably the best option. So access could be revoked in a more timely manner.
from policybasedauthwithblazor.
Right, i understand your point, but the drawback is high. An alternativ approach could be using nginx to handle the revocation list on a lower network level or to use a sync on each service handled by a IHostedService background task.
from policybasedauthwithblazor.
The drawback is high for what?
from policybasedauthwithblazor.
Checking the authentication state against the backend each time the AuthorizeView is displayed. It requires the auth service to be up which is a single point of failure.
from policybasedauthwithblazor.
Yes, as I said in my first reply, I don’t disagree the code could be improved.
from policybasedauthwithblazor.
Thank you, i just thought i missed an implementation detail. So i tried to verify this.
By the way, you have a great blog with nice tutorials. Keep up the great work. :)
from policybasedauthwithblazor.
Related Issues (5)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from policybasedauthwithblazor.