OsharpNS轻量级.net core快速开发框架简明入门教程-Osharp.Permissions使用
OsharpNS轻量级.net core快速开发框架简明入门教程
教程目录
- 从零开始启动Osharp - 1.1. 使用OsharpNS项目模板创建项目 - 1.2. 配置数据库连接串并启动项目 - 1.3. OsharpNS.Swagger使用实例(登录和授权) - 1.4. Angular6的前端项目启动 
- Osharp代码生成器的使用 - 2.1 生成器的使用 
- Osharp部分模块使用 - 3.1 Osharp.Redis使用 
- Osharp深度学习和使用 - 4.2 多上下文配置(多个数据库的使用) - 4.3. 自定义模块的定义(Senparc.Weixin的使用) - 4.4. 继续学习中.... 
OsharpNS官方资源
项目地址:https://github.com/i66soft/osharp-ns20
演示地址:https://www.osharp.org 直接使用QQ登录可以查看效果
文档地址:https://docs.osharp.org 正在完善中....
发布博客:https://www.cnblogs.com/guomingfeng/p/osharpns-publish.html 大神看这个文档应该就能跑起来,从零开始启动Osharp基于此文档完成
VS生成器插件:https://marketplace.visualstudio.com/items?itemName=LiuliuSoft.osharp
官方交流QQ群:85895249
Osharp.Permissions使用
- 系统授权检查流程 - 核心代码位于 - Osharp/Secutiry/FunctionAuthorizationBase- 检查过程如下: - 检查function是否为null,为null反馈错误,否则继续检查 
- 检查function是否被禁用,被禁用反馈错误,否则继续检查 
- 检查功能是否任何人可用,如果是,直接返回成功,否则继续检查 
- 检查用户是否登陆,未登录反馈错误,否则继续检查 
- 用户已登陆,判断功能是否登陆即可使用,如果是,反馈成功,否则继续检查 
- 获取用户的角色,判断角色是否有角色允许执行功能,如果是,反馈成功,否则继续检查 
- 获取用户能执行的所有功能,判断是否包含功能,如果是,反馈成功;如果否,反馈失败(系统除了给定用户角色,还能根据用户单独给定功能授权,所以检查完角色之后不满足条件,还要检查用户私有的功能是否包含) 
 - /// <summary>
 /// 重写以实现权限检查核心验证操作
 /// </summary>
 /// <param name="function">要验证的功能信息</param>
 /// <param name="principal">当前用户在线信息</param>
 /// <returns>功能权限验证结果</returns>
 protected virtual AuthorizationResult AuthorizeCore(IFunction function, IPrincipal principal)
 {
 if (function == null)
 {
 return new AuthorizationResult(AuthorizationStatus.NoFound);
 }
 if (function.IsLocked)
 {
 return new AuthorizationResult(AuthorizationStatus.Locked, $"功能“{function.Name}”已被禁用,无法执行");
 }
 if (function.AccessType == FunctionAccessType.Anonymouse)
 {
 return AuthorizationResult.OK;
 }
 //未登录
 if (principal == null || !principal.Identity.IsAuthenticated)
 {
 return new AuthorizationResult(AuthorizationStatus.Unauthorized);
 }
 //已登录,无角色限制
 if (function.AccessType == FunctionAccessType.Logined)
 {
 return AuthorizationResult.OK;
 }
 return AuthorizeRoleLimit(function, principal);
 } /// <summary>
 /// 重写以实现 角色限制 的功能的功能权限检查
 /// </summary>
 /// <param name="function">要验证的功能信息</param>
 /// <param name="principal">用户在线信息</param>
 /// <returns>功能权限验证结果</returns>
 protected virtual AuthorizationResult AuthorizeRoleLimit(IFunction function, IPrincipal principal)
 {
 //角色限制
 if (!(principal.Identity is ClaimsIdentity identity))
 {
 return new AuthorizationResult(AuthorizationStatus.Error, "当前用户标识IIdentity格式不正确,仅支持ClaimsIdentity类型的用户标识");
 }
 //检查角色-功能的权限
 string[] userRoleNames = identity.GetRoles().ToArray();
 AuthorizationResult result = AuthorizeRoleNames(function, userRoleNames);
 if (result.IsOk)
 {
 return result;
 }
 result = AuthorizeUserName(function, principal.Identity.GetUserName());
 return result;
 } /// <summary>
 /// 重写以实现指定角色是否有执行指定功能的权限
 /// </summary>
 /// <param name="function">功能信息</param>
 /// <param name="roleNames">角色名称</param>
 /// <returns>功能权限检查结果</returns>
 protected virtual AuthorizationResult AuthorizeRoleNames(IFunction function, params string[] roleNames)
 {
 Check.NotNull(roleNames, nameof(roleNames)); if (roleNames.Length == 0)
 {
 return new AuthorizationResult(AuthorizationStatus.Forbidden);
 }
 if (function.AccessType != FunctionAccessType.RoleLimit || roleNames.Contains(SuperRoleName))
 {
 return AuthorizationResult.OK;
 }
 string[] functionRoleNames = FunctionAuthCache.GetFunctionRoles(function.Id);
 if (roleNames.Intersect(functionRoleNames).Any())
 {
 return AuthorizationResult.OK;
 }
 return new AuthorizationResult(AuthorizationStatus.Forbidden);
 } /// <summary>
 /// 重写以实现指定用户是否有执行指定功能的权限
 /// </summary>
 /// <param name="function">功能信息</param>
 /// <param name="userName">用户名</param>
 /// <returns>功能权限检查结果</returns>
 protected virtual AuthorizationResult AuthorizeUserName(IFunction function, string userName)
 {
 if (function.AccessType != FunctionAccessType.RoleLimit)
 {
 return AuthorizationResult.OK;
 } Guid[] functionIds = FunctionAuthCache.GetUserFunctions(userName);
 if (functionIds.Contains(function.Id))
 {
 return AuthorizationResult.OK;
 }
 return new AuthorizationResult(AuthorizationStatus.Forbidden);
 }
 
- Controller里面对是否检查权限的控制 - 文件路径为 - CanDoo.Test.Web.Areas.Admin.Controllers,注意看文件中的- [RoleLimit],带了这个就要做检查- // -----------------------------------------------------------------------
 // <copyright file="AdminApiController.cs" company="OSharp开源团队">
 // Copyright (c) 2014-2018 OSharp. All rights reserved.
 // </copyright>
 // <site>http://www.osharp.org</site>
 // <last-editor>郭明锋</last-editor>
 // <last-date>2018-06-27 4:50</last-date>
 // ----------------------------------------------------------------------- using Microsoft.AspNetCore.Mvc; using OSharp.AspNetCore.Mvc;
 using OSharp.Core; namespace CanDoo.Test.Web.Areas.Admin.Controllers
 {
 [Area("Admin")]
 [RoleLimit]
 public abstract class AdminApiController : AreaApiController
 { }
 }
 
- 不通过数据库强制给定用户角色的方法 - 3.1 通过Claim实现 - 在`IdentityController.cs`中,用户登陆后,生成Claim时,将角色给定
 - private async Task<string> CreateJwtToken(User user)
 {
 //在线用户缓存
 IOnlineUserCache onlineUserCache = HttpContext.RequestServices.GetService<IOnlineUserCache>();
 if (onlineUserCache != null)
 {
 await onlineUserCache.GetOrRefreshAsync(user.UserName);
 } //生成Token,这里只包含最基本信息,其他信息从在线用户缓存中获取
 Claim[] claims =
 {
 new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
 new Claim(ClaimTypes.Name, user.UserName),
 new Claim("ExtendRoles", "学生") //这行是新增的,强制给定学生角色,用户角色表中不存在 用户和学生 角色的关联
 };
 OsharpOptions options = HttpContext.RequestServices.GetService<IOptions<OsharpOptions>>().Value;
 string token = JwtHelper.CreateToken(claims, options);
 return token;
 }
 - 在`CanDoo.Test.Core`中新建类`OnlineUserJwtSecurityTokenHandler.cs`
 - // -----------------------------------------------------------------------
 // <copyright file="OnlineUserJwtSecurityTokenHandler.cs" company="OSharp开源团队">
 // Copyright (c) 2014-2018 OSharp. All rights reserved.
 // </copyright>
 // <site>http://www.osharp.org</site>
 // <last-editor>郭明锋</last-editor>
 // <last-date>2018-07-09 15:01</last-date>
 // ----------------------------------------------------------------------- using System.IdentityModel.Tokens.Jwt;
 using System.Security.Claims; using Microsoft.IdentityModel.Tokens; using OSharp.Collections;
 using OSharp.Dependency;
 using OSharp.Identity;
 using OSharp.Secutiry.Claims; namespace CanDoo.Test.Identity
 {
 /// <summary>
 /// 使用在线用户信息和JwtToken生成在线ClaimsIdentity
 /// </summary>
 public class OnlineUserJwtSecurityTokenHandler : JwtSecurityTokenHandler
 {
 /// <summary>
 /// Creates a <see cref="T:System.Security.Claims.ClaimsIdentity" /> from a <see cref="T:System.IdentityModel.Tokens.Jwt.JwtSecurityToken" />.
 /// </summary>
 /// <param name="jwtToken">The <see cref="T:System.IdentityModel.Tokens.Jwt.JwtSecurityToken" /> to use as a <see cref="T:System.Security.Claims.Claim" /> source.</param>
 /// <param name="issuer">The value to set <see cref="P:System.Security.Claims.Claim.Issuer" /></param>
 /// <param name="validationParameters"> Contains parameters for validating the token.</param>
 /// <returns>A <see cref="T:System.Security.Claims.ClaimsIdentity" /> containing the <see cref="P:System.IdentityModel.Tokens.Jwt.JwtSecurityToken.Claims" />.</returns>
 protected override ClaimsIdentity CreateClaimsIdentity(JwtSecurityToken jwtToken,
 string issuer,
 TokenValidationParameters validationParameters)
 {
 ClaimsIdentity identity = base.CreateClaimsIdentity(jwtToken, issuer, validationParameters);
 var extendRoles = identity.GetClaimValueFirstOrDefault("ExtendRoles");//从Claim中获取强制给定的角色 if (identity.IsAuthenticated)
 {
 //由在线缓存获取用户信息赋给IIdentity
 IOnlineUserCache onlineUserCache = ServiceLocator.Instance.GetService<IOnlineUserCache>();
 OnlineUser user = onlineUserCache.GetOrRefresh(identity.Name);
 if (user == null)
 {
 return null;
 } if (!string.IsNullOrEmpty(user.NickName))
 {
 identity.AddClaim(new Claim(ClaimTypes.GivenName, user.NickName));
 }
 if (!string.IsNullOrEmpty(user.Email))
 {
 identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
 }
 //这部分将从Claim中获取的角色进行赋值
 string roles = "";
 if (user.Roles.Length > 0)
 roles = user.Roles.ExpandAndToString() + "," + extendRoles;
 else
 roles = extendRoles; if (roles != "")
 identity.AddClaim(new Claim(ClaimTypes.Role, user.Roles.ExpandAndToString()));
 } ScopedDictionary dict = ServiceLocator.Instance.GetService<ScopedDictionary>();
 dict.Identity = identity;
 return identity;
 }
 }
 }
 - 对`CanDoo.Test.Core`中`IdentityPack`中的代码进行调整
 - jwt.SecurityTokenValidators.Clear();
 jwt.SecurityTokenValidators.Add(new OnlineUserJwtSecurityTokenHandler());//这里要使用本文中创建的OnlineUserJwtSecurityTokenHandler jwt.Events = new JwtBearerEvents()
 {
 // 生成SignalR的用户信息
 OnMessageReceived = context =>
 {
 string token = context.Request.Query["access_token"];
 string path = context.HttpContext.Request.Path;
 if (!string.IsNullOrEmpty(token) && path.Contains("hub"))
 {
 context.Token = token;
 } return Task.CompletedTask;
 }
 };
 - 3.2 通过替换现有OnlineUserProvider缓存方法实现 - 在`CanDoo.Test.Core`中新建`MyOnlineUserProvider`
 - // -----------------------------------------------------------------------
 // <copyright file="OnlineUserProvider.cs" company="OSharp开源团队">
 // Copyright (c) 2014-2018 OSharp. All rights reserved.
 // </copyright>
 // <site>http://www.osharp.org</site>
 // <last-editor>郭明锋</last-editor>
 // <last-date>2018-08-17 22:36</last-date>
 // ----------------------------------------------------------------------- using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks; using Microsoft.AspNetCore.Identity;
 using Microsoft.Extensions.DependencyInjection;
 using OSharp.Identity; namespace CanDoo.Test.Identity
 {
 /// <summary>
 /// 在线用户信息提供者
 /// </summary>
 public class MyOnlineUserProvider<TUser, TUserKey, TRole, TRoleKey> : IOnlineUserProvider
 where TUser : UserBase<TUserKey>
 where TUserKey : IEquatable<TUserKey>
 where TRole : RoleBase<TRoleKey>
 where TRoleKey : IEquatable<TRoleKey>
 {
 /// <summary>
 /// 创建在线用户信息
 /// </summary>
 /// <param name="provider">服务提供器</param>
 /// <param name="userName">用户名</param>
 /// <returns>在线用户信息</returns>
 public virtual async Task<OnlineUser> Create(IServiceProvider provider, string userName)
 {
 UserManager<TUser> userManager = provider.GetService<UserManager<TUser>>();
 TUser user = await userManager.FindByNameAsync(userName);
 if (user == null)
 {
 return null;
 }
 IList<string> roles = await userManager.GetRolesAsync(user); roles.Add("学生");//这样就强制给用户赋值了,当然可以对其他东西也做手脚 RoleManager<TRole> roleManager = provider.GetService<RoleManager<TRole>>();
 bool isAdmin = roleManager.Roles.Any(m => roles.Contains(m.Name) && m.IsAdmin);
 return new OnlineUser()
 {
 Id = user.Id.ToString(),
 UserName = user.UserName,
 NickName = user.NickName,
 Email = user.Email,
 HeadImg = user.HeadImg,
 IsAdmin = isAdmin,
 Roles = roles.ToArray()
 };
 }
 }
 }
 - 对`CanDoo.Test.Core`中的`IdentityPack`修改代码,将原有的`OnlineUserProvider`换为`MyOnlineUserProvider`
 - /// <summary>
 /// 将模块服务添加到依赖注入服务容器中
 /// </summary>
 /// <param name="services">依赖注入服务容器</param>
 /// <returns></returns>
 public override IServiceCollection AddServices(IServiceCollection services)
 {
 services.AddScoped<IIdentityContract, IdentityService>();
 base.AddServices(services);
 services.Replace(new ServiceDescriptor(typeof(IOnlineUserProvider), typeof(MyOnlineUserProvider<User, int, Role, int>), ServiceLifetime.Scoped));
 return services;
 }
 
OsharpNS轻量级.net core快速开发框架简明入门教程-Osharp.Permissions使用的更多相关文章
- OsharpNS轻量级.net core快速开发框架简明入门教程-Osharp.Redis使用
		OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ... 
- OsharpNS轻量级.net core快速开发框架简明入门教程-Osharp.Hangfire使用
		OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ... 
- OsharpNS轻量级.net core快速开发框架简明入门教程-从零开始启动Osharp
		OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ... 
- OsharpNS轻量级.net core快速开发框架简明入门教程-代码生成器的使用
		OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ... 
- OsharpNS轻量级.net core快速开发框架简明入门教程-基于Osharp实现自己的业务功能
		OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ... 
- OsharpNS轻量级.net core快速开发框架简明入门教程-切换数据库(从SqlServer改为MySql)
		OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ... 
- OsharpNS轻量级.net core快速开发框架简明入门教程-多上下文配置(多个数据库的使用)
		OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ... 
- 【开源】OSharpNS,轻量级.net core快速开发框架发布
		OSharpNS简介 OSharp Framework with .NetStandard2.0(OSharpNS)是OSharp的以.NetStandard2.0为目标框架,在AspNetCore的 ... 
- [开源]OSharpNS - .net core 快速开发框架 - 快速开始
		什么是OSharp OSharpNS全称OSharp Framework with .NetStandard2.0,是一个基于.NetStandard2.0开发的一个.NetCore快速开发框架.这个 ... 
随机推荐
- 【转】Visual Studio 2008 可扩展性开发(二):Macro和Add-In初探
			前言 在VS概览中,我们简单回顾了一下VS的历史.本文将通过两个简单的例子来说明Macro和Add-In的开发.通过Macro我们把VS中的一些重复操作录制下来,之后可以多次运行,节省时间并保持好的心 ... 
- 百度编辑器UEditor,保存图片的配置问题
			前言: 在使用百度编辑器UEditor的时候,如何将图片保存到服务器,我刚开始以为是要自己写上传文件的方法,后来发现只需要配置一下即可,如果你也正在使用百度富文本编辑器UEditor的话,这篇文章将非 ... 
- jmeter-分布式压测部署之负载机的设置
			本文分三个部分: 1.windows下负载机的配置 2.Linux下负载机的配置 3.遇到的问题 *************************************************** ... 
- SpringBoot+Swagger整合
			0.引言及注意事项 Swagger是一个接口文档工具,依照Swagger可以0配置开发接口.不过要注意,Swagger是基于SpringBoot1.47版本开发的,而SpringBoot现在基本都是是 ... 
- 轻量级手绘软件openCanvas免费版,手绘板CG手绘软件
			轻量级手绘软件openCanvas免费版,手绘板CG手绘软件 手绘软件通俗一点来说就是用手来绘画的软件,应用很宽泛如建筑,服饰陈列设计.橱窗设计.家居软装设计.空间花艺设计.美术.园林.环艺.摄影.工 ... 
- 深入理解枚举属性与for-in和for-of
			首先要分清什么是可枚举属性,什么是不可枚举属性 1.可枚举属性 在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的.可枚举性决定了这个属性能否被f ... 
- 带你理解Xcode Derived Data
			什么是Xcode Derived Data?为什么它很重要呢? “Clean derived data”,当你遇到一些极其奇怪的构建问题时,你也许经常听到这句话. Derived Data是一个文件夹 ... 
- Struts2  在Action中操作数据
			Servlet存储数据的方式 在Servlet中,使用ServletContext对象来存储整个WebApp的数据,ServletContext中直接存储整个WebApp的公共数据,可使用set|ge ... 
- PowerShell美化
			转载自Powershell 美化 --oh-my-posh,作者Zvonimir. PowerShell默认的主题太丑了,用过OhMyZsh之后是无法忍受这种丑陋的,幸好PowerShell有对应的O ... 
- JAVA的toString方法的一个小例子
			Object是一个抽象类,他有很有方法,其中的toString方法是我们常见的一个方法,我们可以看这段代码 package com.com.day1; public class ToStringTes ... 
