Code Monkey home page Code Monkey logo

Comments (9)

chrissainty avatar chrissainty commented on June 18, 2024 1

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.

chrissainty avatar chrissainty commented on June 18, 2024 1

@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.

endeffects avatar endeffects commented on June 18, 2024

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.

chrissainty avatar chrissainty commented on June 18, 2024

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.

endeffects avatar endeffects commented on June 18, 2024

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.

chrissainty avatar chrissainty commented on June 18, 2024

The drawback is high for what?

from policybasedauthwithblazor.

endeffects avatar endeffects commented on June 18, 2024

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.

chrissainty avatar chrissainty commented on June 18, 2024

Yes, as I said in my first reply, I don’t disagree the code could be improved.

from policybasedauthwithblazor.

endeffects avatar endeffects commented on June 18, 2024

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 photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.