1、基于角色-权限-资源的权限控制(较细粒度)
2、基于角色策略的权限控制(粗粒度)
初始数据库的时候,框架已经初始了部分资源,在Web.DB.InitDatas类。你可以在管理后台UI界面添加资源或者Web.DB.InitDatabase.cs类初始资源,此类不会自动生成覆盖,更新项目的时候也不会被覆盖
var ress = new Res[]
{
……
new Res {Name="地区列表",Value="Sys_Area_List"},
new Res {Name="地区详情",Value="Sys_Area_Get"},
new Res {Name="地区添加",Value="Sys_Area_Add"},
new Res {Name="地区修改",Value="Sys_Area_Update"},
new Res {Name="地区删除",Value="Sys_Area_Delete"},
new Res {Name="地区批量删除",Value="Sys_Area_BatchDelete"},
……
};
context.Ress.AddRange(ress);
注意:
①Name资源描述
②Value资源值。组成:模块名称_实体类名称_action方法。权限控制会根据角色拥有的权限,
权限拥有的资源,判断某个用户是否拥有访问某个资源的能力。资源值不区分大小写!!!
建议通过管理后台UI界面添加权限,并给权限赋予访问的资源值
//添加权限
Authority authority = new Authority() { Name = "图片管理", Code = "image_manger" };
authorityBll.Add(authority);
//赋予权限资源
Res res = resBll.SelectOne(o => o.Id == 3);
AuthorityRes authorityRes = new AuthorityRes() { Authority = authority,Res= res };
authorityResBll.Add(authorityRes);
建议通过管理后台UI界面添加角色,并给角色赋予访问的权限
//添加角色
Role role = new Role() { Name = "管理员", Code = "manger" };
roleBll.Add(role);
//查询权限
Authority authority = authorityBll.SelectOne(o => o.Id == 2);
//添加角色权限
RoleAuthority roleAuthority = new RoleAuthority() {Role=role,Authority=authority };
roleAuthorityBll.Add(roleAuthority);
此步骤框架自动加载,无须人工干预
Web.Security.AuthorityLoadWebApp实现了Web.Util.IWebApp接口,框架在启动的时候,自动调用此类的OnStarted()方法,加载数据库所有角色及对应的资源到缓存。
var roles = roleBll.SelectAll();
foreach (var r in roles)
{
//角色对应资源序号索引
List<int> ressindex = new List<int>();
//角色对应权限
var roleAuthorites = roleAuthorityBll.SelectAll(o => o.RoleId == r.Id);
foreach (var a in roleAuthorites)
{
//权限对应资源
var authorityRess = authorityResBll.SelectAll(o => o.AuthorityId == a.AuthorityId);
foreach (var _authorityRes in authorityRess)
{
int idx = roleRess.GetResIndex(_authorityRes.Res.Value);
if (idx != -1)//资源存在添加到角色资源列表
{
ressindex.Add(idx);
}
}
}
//保存对应角色和资源下标索引
roleRess.AddRoleRess(r.Code, ressindex);
}
cache.Set(RoleResMap.CACHE_KEY, roleRess);
[Route("api/[controller]/[action]")]
[ApiController]
[Authority(Module ="Sys")] //加在控制器,控制器内所有方法需登录且具有访问对应资源的权限
public class AreaController : MyBaseController
{
IAreaBll bll{geet;set;};
[HttpGet]
public Result List([FromQuery] Dictionary<string, string> where)
{
return Result.Success("succeed").SetData(bll.Query(where));
}
}
[Route("api/[controller]/[action]")]
[ApiController]
public class AreaController : MyBaseController
{
IAreaBll bll{geet;set;};
[HttpGet]
[Authority(Module ="Sys")] //加在操作方法,某个方法需登录且具有访问对应资源的权限
public Result List([FromQuery] Dictionary<string, string> where)
{
return Result.Success("succeed").SetData(bll.Query(where));
}
}
注意:
①Module模块名称与添加资源时的模块名称保持一致,比如Value="Sys_Area_List",因为Authority过滤器当用户在访问
某个方法资源时,会自动获取当前控制器名和方法名称,通过"模块名称_控制器名称_方法名称"构成完整的资源值。如果添加资源的时候,资源值
没有模块名称,Module不需要赋值
②当角色为超级管理员admin的时候,拥有所有权限,即不需要验证权限
[HttpGet("getuserinfo")]
[Authority(Access = AccessType.Login)]
public Result<User> GetUserinfo()
{
User obj = null;
obj = this.userBll.SelectOne(MyUser.Id);
if (obj != null)
{
obj.Pswd = "";
return Result<User>.Success("获取成功").SetData(obj);
}
return Result<User>.Error("获取失败").SetData(new User() { });
}
[Route("api/[controller]/[action]")]
[ApiController]
[Authorize()] //加在控制器,控制器内所有方法需登录访问
public class AreaController : MyBaseController
{
IAreaBll bll{geet;set;};
[HttpGet]
public Result List([FromQuery] Dictionary<string, string> where)
{
return Result.Success("succeed").SetData(bll.Query(where));
}
}
[Route("api/[controller]/[action]")]
[ApiController]
public class AreaController : MyBaseController
{
IAreaBll bll{geet;set;};
[HttpGet]
[Authorize()] //加在操作方法,某个方法需登录访问
public Result List([FromQuery] Dictionary<string, string> where)
{
return Result.Success("succeed").SetData(bll.Query(where));
}
}
内置策略名称有:admin策略对应角色admin,user策略对应角色user
//加在控制器,控制器内所有方法需登录访问
[Route("api/[controller]/[action]")]
[ApiController]
[Authorize("admin")] //策略为admin才能访问
public class AreaController : MyBaseController
{
IAreaBll bll{geet;set;};
[HttpGet]
public Result List([FromQuery] Dictionary<string, string> where)
{
return Result.Success("succeed").SetData(bll.Query(where));
}
}
注:如何自定义策略名称
1.策略名称在Web/Jwt/JwtExtension.cs文件定义注册。一个策略名称对应一个或多个__角色__
#region 授权
services.AddAuthorization(options =>
{
//AddPolicy("admin" 自定义策略名称
//policy => policy.RequireRole("admin")策略要求角色,一个策略可以有多个角色
options.AddPolicy("admin", policy => policy.RequireRole("admin").Build());
options.AddPolicy("teacher", policy => policy.RequireRole("teacher","admin").Build());
options.AddPolicy("student", policy => policy.RequireRole("student").Build());
});
#endregion
2.角色名称与登录时候生成token的角色名称保持一致。在Web/Controllers/DefaultController.cs登录方法生成__token__
public class DefaultController : MyBaseController
{
[HttpPost("login")]
public Result Login(Userinfo o)
//public Result Login([FromForm]string username, [FromForm]string password,[FromForm]string type="student")
{
……
if (obj != null)
{
type = o.Type;
var t = new Token() { Uid = obj.Id, Uname = obj.Username, Role = obj.Role, Type = type, TokenType = TokenType.App, Project = project,ClasssId= classid,SchoolId = schoolid };
return Result.Success("登录成功")
.SetData(new Userinfo() { Id = obj.Id, Username = obj.Username, Avatar = obj.Photo, Role = obj.Role, Type = o.Type, Realname = obj.Realname, Tel = obj.Tel, Email = obj.Email, Birthday = obj.Birthday, Token = JwtHelper.IssueJWT(t, this.jwtConfig) });
}
return Result.Error("登录失败,用户名密码错误").SetData(new Userinfo() { Token = "" });
}
}
这里Role = obj.Role就是生成token的角色名称。token生成后传递给客户端,客户端每次请求服务端api时携带这个token,然后服务端收到token并解析出角色。
而服务端控制器或方法的**[Authorize("admin")]**注解根据策略名称在上面注册的策略查询到策略对应的角色,与客户端所带token的角色对比,看控制器或方法所需的角色是否包含token的角色, 如果包含表示有权限,反之,无权限。
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )