当前位置: 首页 > news >正文

韩国私人网站服务器南阳手机网站推广

韩国私人网站服务器,南阳手机网站推广,网上智慧团建登录入口,泰安网红餐厅环境VS 2017ASP.NET Core 2.2目标以相对简单优雅的方式实现用户身份验证和鉴权#xff0c;解决以下两个问题#xff1a;无状态的身份验证服务#xff0c;使用请求头附加访问令牌#xff0c;几乎适用于手机、网页、桌面应用等所有客户端基于功能点的权限访问控制#xff0c… 环境VS 2017ASP.NET Core 2.2目标  以相对简单优雅的方式实现用户身份验证和鉴权解决以下两个问题无状态的身份验证服务使用请求头附加访问令牌几乎适用于手机、网页、桌面应用等所有客户端基于功能点的权限访问控制可以将任意功能点权限集合授予用户或角色无需硬编码角色权限非常灵活项目准备创建一个ASP.NET Core Web应用程序使用ASP.NET Core 2.2模板选[空]不启用HTTPS不进行身份验证通过NuGet安装Swashbuckle.AspNetCore程序包并在Startup类中启用Swagger支持因为这个示例项目不打算编写前端网页所以直接使用Swagger来调试真的很方便。添加一个空的MVC控制器(HomeController)和一个空的API控制器(AuthController)HomeController.Index()方法中只写一句简单的跳转代码即可return new RedirectResult(~/swagger);AuthController类中随便写一两个骨架方法方便看效果。运行项目会自动打开浏览器并跳转到Swagger页面。身份验证定义基本类型和接口ClaimTypes 定义一些常用的声明类型常量IClaimsSession 表示当前会话信息的接口ClaimsSession 会话信息实现类根据声明类型从ClaimsPrincipal.ClaimsIdentity属性中读取用户ID、用户名等信息。实际项目中可从此类继承或完全重新实现自己的Session类以添加更多的会话信息(例如工作部门)IToken 登录令牌接口包含访问令牌、刷新令牌、令牌时效等令牌IIdentity 身份证明接口包含用户基本信息及令牌信息IAuthenticationService 验证服务接口抽象出来的验证服务接口仅规定了四个身份验证相关的方法如需扩展可定义由此接口派生的接口。Login(userName, password)IIdentity根据用户名及密码验证其身份成功则返回身份证明Logout()void注销本次登录即使未登录也不报错RefreshToken(refreshToken)Token刷新登录令牌如果当前用户未登录则报错ValidateToken(accessToken)IIdentity验证访问令牌成功则返回身份证明SimpleToken 登录令牌的简化实现这个类提不提供都可以实际项目中大家生成Token的算法肯定是各不相同的提供简单实现仅用于演示编写验证处理器BearerDefaults 定义了一些与身份验证相关的常量如AuthenticationSchemeBearerOptions 身份验证选项类从AuthenticationSchemeOptions继承而来BearerValidatedContext 验证结果上下文BearerHandler 身份验证处理器  关键类覆盖了HandleAuthenticateAsync()方法实现自定义的身份验证逻辑简述如下获取访问令牌。从请求头中获取authorization信息如果没有则从请求的参数中获取如果访问令牌为空则终止验证但不报错直接返回AuthenticateResult.NoResult()调用从构造函数注入的IAuthenticationService实例的ValidateToken()方法验证访问令牌是否有效如果该方法触发异常(例如令牌过期)则捕获后通过AuthenticateResult.Fail()返回错误信息如果该方法返回值为空(例如访问令牌根本不存在)则返回AuthenticateResult.NoResult()不报错。到这一步说明身份验证已经通过而且拿到身份证明信息根据该信息创建Claim数组然后再创建一个包含这些Claim数据的ClaimsPrincipal实例并将Thread.CurrentPrincipal设置为该实例。重点其实HttpContext.User属性的类型正是CurrentPrincipal而其值应该就是来自于Thread.CurrentPrincipal。构造BearerValidatedContext实例并将其Principal属性赋值为上面创建的ClaimsPrincipal实例然后调用Success()方法表示验证成功。最后返回该实例的Result属性值。BearerExtensions 包含一些扩展方法提供使用便利重点在于AddBearer()方法内调用builder.AddSchemeTOptions,THandler()泛型方法时分别使用了前面编写的BearerOptions、BearerHandler类作为泛型参数。public static AuthenticationBuilder AddBearer(...){return builder.AddSchemeBearerOptions, BearerHandler(...);}如果想要自己实现BearerHandler类的验证逻辑可以抛弃此类重新编写使用新Handler类的扩展方法实现用户身份验证说明  这部分是身份验证的落地实际项目中应该将上面两步(定义基本类型和接口、编写验证处理器)的代码抽象出来成为独立可复用的软件包利用该软件包进行身份验证的实现逻辑可参照此示例代码。实现步骤Identity 身份证明实现类SampleAuthenticationService 验证服务的简单实现出于演示方便固化了三个用户(admin/123456、user/123、tester/123)AuthController 通过HTTP向前端提供验证服务的控制器类提供了用户登录、令牌刷新、令牌验证等方法。还需要修改项目中Startup.cs文件添加依赖注入规则、身份验证并启用身份验证中间件。在ConfigureServices方法内添加代码services.AddScopedIClaimsSession, ClaimsSession();services.AddScopedIAuthenticationService, SampleAuthenticationService();services.AddAuthentication(options { options.DefaultAuthenticateScheme BearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme BearerDefaults.AuthenticationScheme;}).AddBearer();在Configure()方法内添加代码app.UseAuthentication();通过Swagger测试测试登录功能启动项目自动进入[Swagger UI]界面点击/api/Auth/Login方法不修改输入框中的内容直接点击[Execute]按钮可以见到返回401错误码。在输入框中输入{userName: admin, password: 123456}然后点击[Execute]按钮系统验证成功并返回身份证明信息。记下访问令牌2ad43df2c11d48a18a88441adbf4994a和刷新令牌9bbaf811ed8b4d29b638777d4f89238e测试刷新登录令牌点击/api/Auth/Refresh方法在输入框中输入上面获取到的刷新令牌9bbaf811ed8b4d29b638777d4f89238e然后点击[Execute]按钮返回401错误码。原因是因为我们并未提供访问令牌。点击方法名右侧的[锁]图标在弹出框中输入之前获取的访问令牌2ad43df2c11d48a18a88441adbf4994a并点击[Authorize]按钮后关闭对话框重新点击[Execute]按钮成功获取到新的登录令牌。测试验证访问令牌点击/api/Auth/Validate方法在输入框中输入第一次获取的到访问令牌2ad43df2c11d48a18a88441adbf4994a然后点击[Execute]按钮返回400错误码表明发起的请求参数有误。因为此方法是支持匿名访问的所以错误码不会是401.将输入框内容修改为新的访问令牌f37542e162ed4855921ddf26b05c3f25然后点击[Execute]按钮验证成功返回了对应的用户身份证明信息。权限鉴定  在ASP.NET Core项目中实现基于角色的授权很容易在一些权限管理并不复杂的项目中采取这种方式来实现权限鉴定简单可行。有兴趣可以参考这篇博文ASP.NET Core 认证与授权5:初识授权  但是对于稍微复杂一些的项目权限划分又细又多如果采用这种方式要覆盖到各种各样的权限组合需要在代码中定义相当多的角色大大增加项目维护工作并且很不灵活。  这里借鉴ABP框架中权限鉴定的一些思想来实现基于功能点的权限访问控制。  非常感谢ASP.NET Core和ABP等诸多优秀的开源项目向你们致敬  不得不说ABP框架非常优秀但是我并不喜欢使用它因为我没有能力和精力搞清楚它的详细设计思路而且很多功能我根本不需要。思路  ASP.NET Core提供了一个IAuthorizationFilter接口如果在控制器类上添加[授权过滤]特性相应的AuthorizationFilter类的OnAuthorization()方法会在控制器的Action之前运行如果在该方法中设置AuthorizationFilterContext.Result为一个错误的responseAction将不会被调用。基于这个思路我们设计了以下方案编写一个Attribute(特性)类包含以下两个属性Permissions需要检查的权限数组RequireAllPermissions是否需要拥有数组中全部权限如果为否则拥有任一权限即可定义一个IPermissionChecker接口在接口中定义IsGrantedAsync()方法用于执行权限鉴定逻辑编写一个AuthorizationFilterAttribute特性类(应用目标为class)通过属性注入IPermissionChecker实例。然后在OnAuthorization()方法内调用IPermissionChecker实例的IsGrantedAsync()方法如果该方法返回值为false则返回403错误否则正常放行。编写过滤器类及相关接口ApiAuthorizeAttribute类 [AttributeUsage(AttributeTargets.Method)]public class ApiAuthorizeAttribute : Attribute, IFilterMetadata {public string[] Permissions { get; }public bool RequireAllPermissions { get; set; }public ApiAuthorizeAttribute(params string[] permissions){ Permissions permissions; } }IPermissionChecker接口定义 public interface IPermissionChecker {Taskbool IsGrantedAsync(string permissionName); }AuthorizationFilterAttribute类 [AttributeUsage(AttributeTargets.Class)]public class AuthorizationFilterAttribute : Attribute, IAuthorizationFilter{ [Injection] public IPermissionChecker PermissionChecker { get; set; } NullPermissionChecker.Instance;public void OnAuthorization(AuthorizationFilterContext context) {if(存在[AllowAnonymous]特性) return;var authorizeAttribute 从context.Filters中析出ApiAuthorizeAttribute foreach (var permission in authorizeAttribute.Permissions) {var granted PermissionChecker.IsGrantedAsync(permission).Result; }if(检查未通过) context.Result new ObjectResult(未授权) { StatusCode 403 }; } }配合属性注入提供NullPermissionChecker类在IsGrantedAsync()方法内直接返回true。实现属性注入  做好上面的准备我们应该可以开始着手在项目内应用权限鉴定功能了不过ASP.NET Core内置的DI框架并不支持属性注入所以还得添加属性注入的功能。定义InjectionAttribute类用于显式声明应用了此特性的属性将使用依赖注入[AttributeUsage(AttributeTargets.Property)]public class InjectionAttribute : Attribute { }添加一个PropertiesAutowiredFilterProvider类从DefaultFilterProvider类派生public class PropertiesAutowiredFilterProvider : DefaultFilterProvider{private static IDictionarystring, IEnumerablePropertyInfo _publicPropertyCache new Dictionarystring, IEnumerablePropertyInfo();public override void ProvideFilter(FilterProviderContext context, FilterItem filterItem){base.ProvideFilter(context, filterItem); var filterType filterItem.Filter.GetType();if (!_publicPropertyCache.ContainsKey(filterType.FullName)) {var psfilterType.GetProperties(BindingFlags.Public|BindingFlags.Instance) .Where(c c.GetCustomAttributeInjectionAttribute() ! null); _publicPropertyCache[filterType.FullName] ps; }var injectionProperties _publicPropertyCache[filterType.FullName];if (injectionProperties?.Count() 0)return;var serviceProvider context.ActionContext.HttpContext.RequestServices;foreach (var item in injectionProperties) {var service serviceProvider.GetService(item.PropertyType);if (service null) {throw new InvalidOperationException($Unable to resolve service for type {item.PropertyType.FullName} while attempting to activate {filterType.FullName}); } item.SetValue(filterItem.Filter, service); } }}还有非常关键的一步在Startup.ConfigureServices()中添加下面的代码替换IFilterProvider接口的实现类为上面编写的PropertiesAutowiredFilterProvider类services.Replace(ServiceDescriptor.SingletonMicrosoft.AspNetCore.Mvc.Filters.IFilterProvider, PropertiesAutowiredFilterProvider());实现用户权限鉴定  终于我们可以在项目内应用权限鉴定功能了。编码首先我们定义一些功能点权限常量public static class PermissionNames{public const string TestAdd Test.Add;public const string TestEdit Test.Edit;public const string TestDelete Test.Delete;}接着添加一个新的用于测试的控制器类 [AuthorizationFilter] [Route(api/[controller])] [ApiController]public class TestController : ControllerBase { [Injection]public IClaimsSession Session { get; set; } [HttpGet] [Route([action])]public IActionResult CurrentUser() Ok(Session?.UserName); [ApiAuthorize] [HttpGet({id})]public IActionResult Get(int id) Ok(id); [ApiAuthorize(PermissionNames.TestAdd)] [HttpPost] [Route([action])]public IActionResult Create() Ok(); [ApiAuthorize(PermissionNames.TestEdit, RequireAllPermissions false)] [HttpPost] [Route([action])]public IActionResult Update() Ok(); [ApiAuthorize(PermissionNames.TestAdd, PermissionNames.TestEdit, RequireAllPermissions false)] [HttpPost] [Route([action])]public IActionResult Patch() Ok(); [ApiAuthorize(PermissionNames.TestDelete)] [HttpDelete({id})]public IActionResult Delete(int id) Ok(); }在控制器类上添加了[AuthorizationFilter]特性除了CurrentUser()方法以外都添加了[ApiAuthorize]特性所需的权限各不相同为简化测试所有的Action都直接返回OkResult。实现一个用于演示的权限检查器类public class SamplePermissionChecker : IPermissionChecker{private readonly Dictionarylong, string[] userPermissions new Dictionarylong, string[] { { 1, new[] { PermissionNames.TestAdd, PermissionNames.TestEdit, PermissionNames.TestDelete } }, { 2, new[] { PermissionNames.TestEdit, PermissionNames.TestDelete } } };public IClaimsSession Session { get; }public SamplePermissionChecker(IClaimsSession session){this.Session session; }public Taskbool IsGrantedAsync(string permissionName){if(!userPermissions.Any(p p.Key Session.UserId))return Task.FromResult(false);var up userPermissions.Where(p p.Key Session.UserId).First();var granted up.Value.Any(permission permission.Equals(permissionName, StringComparison.InvariantCultureIgnoreCase));return Task.FromResult(granted); }}最后还需要修改项目中Startup.cs文件添加依赖注入规则services.AddSingletonIPermissionChecker, SamplePermissionChecker();因为SamplePermissionChecker类中并没有需要进程间隔离的数据所以使用单例模式注册就可以了。不过这样一来因为该类通过构造函数注入了IClaimsSession接口实例在构建Checker类实例时将触发异常。考虑到CliamsSession类中只有方法没有数据 改为单例也并无妨于是将该接口也改为单例模式注册。通过Swagger测试测试未登录时仅可访问/api/Test/CurrentUser测试以用户user登录可以访问/api/Test/CurrentUser和GET请求/api/Test/{id}测试以用户admin登录可以访问除/api/Test/Add以外的接口测试编写了命令行程序用来测试前面实现的Web API服务。测试不同用户同时访问时Session是否正确测试方法同时运行三个测试程序都选择[测试身份验证]然后分别输入不同的用户身份序号快速切换三个程序并按下回车键三个测试程序会各自发起100次请求每次请求间隔100毫秒。例如同时打开三个命令行终端执行dotnet .\CustomAuthorization.test.dll测试结果三个测试程序从后台服务所获取到的当前用户信息完成匹配。测试以不同用户身份访问需要权限的接口测试方法预设的权限为admin全部权限user除Test.Add以外权限tester无。分别以admin、user、tester三个用户身份请求/api/test下的所有接口并模拟令牌过期的场景。测试结果可以见到以过期的令牌发起请求时后台返回的状态为Unauthorized当用户未获得足够的授权时后台返回的状态为Forbidden。测试通过最后源代码托管在gitee.com https://gitee.com/xant77/CustomAuthorization.WebApi原文地址https://www.cnblogs.com/wiseant/p/10515842.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com
http://www.sadfv.cn/news/111499/

相关文章:

  • 有哪些外国网站国内可以登录的微网站 报价
  • 找钢网网站建设wordpress常用钩子
  • 深圳小企业网站建设设计制作设计型网站建设
  • 网站建设最新新闻商务网站设计与制作
  • wordpress建站插件安全wap门户网站源码
  • 证书查询官网全能优化大师
  • 免费手工活外发加工网站北京市在建工程项目查询
  • 西安做网站设计的公司网站建设的er图怎么画
  • 辽宁学网站建设专业学校自己创建一个公司
  • 唐山网站建设托管河南建设部网站
  • 老公给人做网站结果网站卖假货常州网站搭建公司
  • 石狮app网站开发wordpress akina
  • asp网站漏洞修复插件dede网站seo
  • 广州网站推广哪家强建设多语种网站
  • 图形网站建设软件淄博网站排名外包
  • 山东网站建设优化技术毕节市网站建设
  • 理卖做各视频网站的会员提交链接
  • 相册管理网站模板下载新闻 近期大事件
  • 酒吧dj做歌网站wordpress标签没反应
  • 网站建设平台资讯建设网站的建设费用包括什么
  • 网站备注销新余门户网站建设
  • 自助外贸英文网站建设wordpress表单编辑插件下载
  • 可以在线制作简历的网站vancl凡客诚品官网
  • 福清网站商城建设soho 网站建设
  • 自助网站建设哪家优惠成都网站建设与网站推广培训
  • 贵阳建设厅网站怎么塔建网站
  • 响应式网站 app网站模板全屏
  • 单项否决 网站建设网上自学平台
  • 网站建设与网页设计张家港普通网站建设
  • 易营宝智能建站手机网站建设服务合同