ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

从零开始Blazor Server(5)--权限验证

2022-08-02 10:02:27  阅读:225  来源: 互联网

标签:NavigateTo NavigationManager return -- Server user var Blazor Login


之前我们一直使用的是微软自带的身份验证方式,即使用[Authorize]标签来做。

但是这种方式十分不灵活,微软推荐的方式是加Policy,但是这种方式对我们来说还是不够灵活。


所以本节我们用完全自己校验的方式完成权限验证。

OnNavigateAsync介绍

在 App.razor 里面的Router节点,微软给了一个OnNavigateAsync方法,这个方法在每次路由跳转的时候都会执行,所以我们可以把我们的权限验证搬到这里来。

App.razor

首先,我们在Router节点上增加OnNavigateAsync

<Router AppAssembly="@typeof(App).Assembly" OnNavigateAsync="PermissionCheck">

这里我们的方法叫做PermissionCheck


然后我们来看这个PermissionCheck方法。

    private void PermissionCheck(NavigationContext context)
    {
        var whiteList = Furion.App.Configuration["WhiteList"];
        if (whiteList != null && whiteList.Split(',').Contains(context.Path))
        {
            return;
        }

        var user = Furion.App.User;
        if (user == null)
        {
            NavigationManager.NavigateTo("/Login");
            return;
        }

        if (user.Identity?.IsAuthenticated != true)
        {
            NavigationManager.NavigateTo("/Login");
            return;
        }

        if (!int.TryParse(user.FindFirst(ClaimTypes.Role)?.Value, out var roleId))
        {
            NavigationManager.NavigateTo("/Login");
            return;
        }

        var permission = PermissionEntity
            .Where(x => x.Roles!.Any(y => y.Id == roleId) && x.Url == context.Path).First();

        if (permission == null)
        {
            NavigationManager.NavigateTo("/Login");
        }

    }

这里我们需要把Login这个页面拿出来,因为我们的Login页面应该是一个白名单页面,无需登录也可以访问,所以我在appsettings.json中增加了一项,为WhiteList,这里面以,分隔,所有在这里面的路径都是白名单路径,可以不用登录直接访问。

"WhiteList": "Login"

这里注意,OnNavigateAsync给的Path是相对路径,不带最前面的/,所以我们的Login也不能有/

这里判断如果是白名单,则直接return,正常跳转。

var user = Furion.App.User;
        if (user == null)
        {
            NavigationManager.NavigateTo("/Login");
            return;
        }

        if (user.Identity?.IsAuthenticated != true)
        {
            NavigationManager.NavigateTo("/Login");
            return;
        }

然后获取我们的登录信息,如果没有登录,那么直接跳转到Login页面。

if (!int.TryParse(user.FindFirst(ClaimTypes.Role)?.Value, out var roleId))
        {
            NavigationManager.NavigateTo("/Login");
            return;
        }

这里获取我们当时在LoginController里的RoleId

这里注意,我稍微改了一下,之前的文章里我们这里面放的是RoleName,本来是打算根据用户再获取权限,但是后来想想有点麻烦,就稍微改动了一下,具体的可以看下新的源码。实战中建议还是不要直接放RoleId进去,因为这个玩意在实战中往往是一对多的。

var permission = PermissionEntity
            .Where(x => x.Roles!.Any(y => y.Id == roleId) && x.Url == context.Path).First();

        if (permission == null)
        {
            NavigationManager.NavigateTo("/Login");
        }

最后我们判断一下数据库里这个角色有没有这个路径的权限,如果没有,我们就跳转。

这样我们就可以实现根据path来判断权限了。

这里由于是教程类的,所以所有的判断我都是直接从数据库里取得,正式使用的时候建议放到缓存里面,如果没有页面都走一次数据库,那么数据库的压力会非常大。

默认数据的路径我稍微修改了一下,去掉了前面的/,这里直接把数据库给删掉,然后重新运行就行了。

源码在github:https://github.com/j4587698/BlazorLearn,分支lesson5

标签:NavigateTo,NavigationManager,return,--,Server,user,var,Blazor,Login
来源: https://www.cnblogs.com/j4587698/p/16542766.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有