0

Edit: I Answerd myself on this post. Its updated.

I authenticate users using the Windows Authenticate from Blazor. Now I want to authorize these users as well, I do this by having the users roll and userId in a database table that looks like this:

UserId RoleId
3 1
7 1
112 1
4 2
7 2
8 2

The actual authorization happens in the CustomAuthenticationStateRrovider.cs

using Microsoft.AspNetCore.Components.Authorization;
using System.Diagnostics;
using System.Security.Claims;

namespace Authtest.Services
{
    public class CustomAuthenticationStateProvider : AuthenticationStateProvider
    {
        private List<UserRoles> userRoles = default!;
        
        public override async Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            var userroleService = new UserRoleService();
            userRoles = userroleService.GetUserRolesListe();

            var identity = new ClaimsIdentity();

            foreach (var role in userRoles)
            {
                Debug.WriteLine($"Adding role {role.RoleId} to identity.");
                identity.AddClaim(new Claim(ClaimTypes.Role, role.RoleId.ToString()));
            }

            var user = new ClaimsPrincipal(identity);

            return new AuthenticationState(user);
        }
    }
}

As you can see in the screenshot the Database query works.Debug var user

The following problem I have now and that is in the index.razor as seen on the 2nd screenshot problem with auth, the Authorized part is displayed although my user has the role 1 and only users with the role 2 should see the text. A Different problem (which depends on the same solution I think) with the LoginDisplay.razor is why always the NotAuthorized part is displayed.

PS: I think the problem is that by creating a new ClaimsPrincipal I override the Windows authentication.

I made a brand new syncfusion blazor server application and put only the authentication part from my project in the new one, so I could try everything out, but nothing worked.

Edit: I even made a more detailed Screenshot from the user variable here.

muhammad tayyab
  • 727
  • 7
  • 18
  • I forgot to mention that I added these builder in my Program.cs builder.Services.AddScoped(); builder.Services.AddScoped(); – Jorgetryingsomething Aug 21 '23 at 11:38
  • 1
    Don't create a new `ClaimsPrincipal`, just create a new `ClaimsIdentity` containing the roles and add it to the existing `ClaimsPrincipal`, A `ClaimsPrincipal` can have multiple identities. Add the new one to the `Identities` property. – MrC aka Shaun Curtis Aug 21 '23 at 13:22
  • I made progress with my index.razor. I can now see the (only with Role 1, like it should be). The other Problem with the LoginDisplay still continues as you can see in the screenshot above ("problem with auth"). Here the code for the first solution `if (string.Equals(userRole.WindowsUser, currentUserName, StringComparison.OrdinalIgnoreCase))` And i Added one more column to my tabele (var userRoles). – Jorgetryingsomething Aug 21 '23 at 14:14
  • I'm kinda with MrC. I was reading this article which adds the role to the ClaimsIdentity.https://learn.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-7.0 Maybe that's why "Role=" isn't working. – USMC6072 Aug 22 '23 at 16:58
  • Mhh, thanks for the answer but that link doesnt help me :/ – Jorgetryingsomething Aug 24 '23 at 07:17

1 Answers1

0

Ok after some research and the comments on this post I tried something diffrent.

<PageTitle>Index</PageTitle>

<AuthorizeView Roles="1">
    <Authorized>
        <p>This content is displayed only for users with role 1.</p>
    </Authorized>
    <NotAuthorized>
        <p>This content is displayed for all other roles and non-authorized users.</p>
    </NotAuthorized>
</AuthorizeView>

I use a CustomAuthenticationStateProvider.cs

using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;

namespace Authtest.Services
{
    public class CustomAuthenticationStateProvider : AuthenticationStateProvider
    {
        private readonly UserRoleService _userRoleService;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public CustomAuthenticationStateProvider(UserRoleService userRoleService, IHttpContextAccessor httpContextAccessor)
        {
            _userRoleService = userRoleService;
            _httpContextAccessor = httpContextAccessor;
        }

        public override async Task<AuthenticationState> GetAuthenticationStateAsync()
        {
            var user = _httpContextAccessor.HttpContext.User;

            if (user.Identity.IsAuthenticated)
            {
                var userRolesList = _userRoleService.GetUserRolesListe();

                var currentUser = userRolesList.FirstOrDefault(ur => ur.WindowsUser == user.Identity.Name);

                if (currentUser != null)
                {
                    var claimsIdentity = (ClaimsIdentity)user.Identity;
                    claimsIdentity.AddClaim(new Claim(ClaimTypes.GroupSid, currentUser.RoleId.ToString()));
                }
            }

            return new AuthenticationState(user);
        }
    }

}

Everything seems to work "http://schemas.microsoft.com/ws/2008/06/identity/claims/role: 1";"LOCAL AUTHORITY";"LOCAL AUTHORITY";System.Security.Principal.WindowsIdentity;http://schemas.microsoft.com/ws/2008/06/identity/claims/role

But I still get shown the Not Authorized Part from my index.razor.

PS: I have builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthenticationStateProvider>(); in my Program.cs

  • I finally did it idk if it is meant to be but it works.I changed the ClaimTypes.Role to ClaimTypes.GroupSid. `claimsIdentity.AddClaim(new Claim(ClaimTypes.GroupSid, currentUser.RoleId.ToString()));` – Jorgetryingsomething Aug 30 '23 at 07:16
  • Just found this Post who had the some problems https://stackoverflow.com/questions/35081037/isinrole-return-false-even-if-there-is-role-in-claims – Jorgetryingsomething Aug 30 '23 at 07:27