Authorization of Blazor page elements - the use of AuthorizeView components

Authorization of Blazor page elements - the use of AuthorizeView components

In the previous blog, we talked about the implementation of blazor's identity authentication. For the AuthorizeView component, the AuthenticationState object containing user information can be obtained through cascading parameters.

Please note that you need to reference the Microsoft.AspNetCore.Components.Authorization Nuget package, and add the service in the startup class and Services.AddAuthorizationCore();
use the CascadingAuthenticationState component to wrap the code in App.razor:

<CascadingAuthenticationState>
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" 
                DefaultLayout="@typeof(MainLayout)" />
        </Found>
        <NotFound>
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
</CascadingAuthenticationState>

If no authorization conditions are specified, AuthorizeView uses a default strategy:

  • Treat authenticated (logged in) users as authorized.
  • Treat unauthenticated (logged out) users as unauthorized.

Role-Based Authorization

Roles can be obtained in various ways, either from the project itself or from an external permission system. In short, you need to know the scope of permissions corresponding to the role itself, such as controlling which pages can be accessed and which buttons are visible.
Keep in mind that doing permission control only on the client side is not secure.

Wrap the components that need to verify the role to view in the AuthorizeView component

<AuthorizeView Roles="admin">
    <p>You can only see this if you're an admin or superuser.</p>
</AuthorizeView>

Personally, I use authentication and authorization as two services. The authorization service calls the authority management system interface according to the system code and module Id. The authority system will return the authority tree according to the current user. After I get the authority tree, I will use the button or the authority identifier of the page as Roles and write In AuthenticationState, use the above example to control the display of page elements.

Attached below is the complete authorization service code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using ClientSideTemplate.Client.Foundation.Authentication.Model;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.WebAssembly.Http;
using Newtonsoft.Json;

namespace ClientSideTemplate.Client.Foundation.Authentication
{
    public class AuthorizedService
    {
        private readonly IServiceClient _serviceClient;
        private readonly AuthorizedOption _authorizedOption;

        public AuthorizedService(IServiceClient serviceClient, AuthorizedOption authorizedOption)
        {
            _serviceClient = serviceClient;
            _authorizedOption = authorizedOption;
        }

        public async Task AuthorizedAsync(AuthenticationState state)
        {
#if DEBUG
            var identity = new ClaimsIdentity(_authorizedOption.ModuleIds.Select(x => new Claim(ClaimTypes.Role, x)));
            state.User.AddIdentity(identity);
#else
            foreach (var moduleId in _authorizedOption.ModuleIds)
            {
                var userInfo = await GetUserInfo(_authorizedOption.SystemCode, moduleId);
                var identity = new ClaimsIdentity(userInfo.PrivilegeTree.Select(x => new Claim(ClaimTypes.Role, x.ModuleId)));
                state.User.AddIdentity(identity);
            }
#endif
        }

        private async Task<UserInfo> GetUserInfo(string systemCode, string moduleId)
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"/login/Auth/UserInfo?systemCode={systemCode}&moduleId={moduleId}");
            request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);

            var response = await _serviceClient.SendAsync(request);
            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
#if !DEBUG
                SignIn();
#endif
            }

            var content = await response.Content.ReadAsStringAsync();
            if (string.IsNullOrWhiteSpace(content))
            {
                return new UserInfo();
            }

            return JsonConvert.DeserializeObject<ApiResult<UserInfo>>(content).Result;
        }
    }
}

Also, if you want to get the AuthenticationState in code, please do so in the form of cascading parameters:

 [CascadingParameter]
private Task<AuthenticationState> authenticationStateTask { get; set; }

Guess you like

Origin blog.csdn.net/qq_40404477/article/details/109346470