准备
创建一个名为AuthorizationForoNetCore的(web)解决方案,选择Empty模板
添加相关nuget包引用Microsoft.AspNetCore.Mvc(选择最新版本)
编辑Startup.cs文件,添加mvcservice并进行默认路由配置
添加Controllers文件夹,添加HomeContrller
创建
Views/Home文件夹,并添加Index(Action)对应的Index.cshtml文件
<!--Index.cshtml-->
假如生活欺骗了你
假如生活欺骗了你,
不要悲伤,不要心急!
忧郁的日子里须要镇静:
相信吧,快乐的日子将会来临!
使用Authorization
添加相关nuget包(均使用最新版本)
Microsoft.AspNetCore.Authorization
Microsoft.AspNetCore.Authentication.Cookies
在ConfigureServices()方法中添加对应服务: services.AddAuthorization()
在Index(Action)方法上添加 [Authorize] 特性,毫无疑问,添加后执行dotnet run 指令后后会返回401的授权码,那么接着操作
编辑Startup.cs在Configureapp.UseMvc()方法之前,我们添加一个cookie 中间件,用于持久化请求管道中的身份配置信息
tip:相关配置参数细节请参阅:https://docs.asp.net/en/latest/security/authentication/cookie.html
添加Controllers/Account文件夹,添加 AccountController.cs 控制器文件,实现上述指定的方法,可能这里你会疑惑,为什么文档里不是一个 /Account/Login 这类的,文档说了别较真,这就是个例子而已,继续你就明白了。
添加并实现上述中间件重定向的action 方法如下,你可以看到其实Unauthorized方法模拟实现了登陆的过程。tip:假如你添加Unauthorized视图,并且没有该不实现模拟登陆,那么运行你会直接看到 Unauthorized.cshtml 的内容,这里我们不需要添加该视图,仅作说明。
编辑
Home/Index.schtml
运行代码你会看到如下结果(程序获取我们提供的由issuer发布claims并展示在视图中,后续会检查Claims看他们是否匹配)
使用全局授权策略
去除Home/Index (Action)上的 [Authorize] 特性
添加 Views/Account/Forbidden.cshtml 页面,内容为 <h1>拒绝访问</h1>
修改 ConfigureServices 方法中的 services.AddMvc() 使用它的 AddMvc(this IServiceCollection services, Action<MvcOptions> setupAction) 重载
运行查看结果,你会发现这几乎成了一个无限的重定向从而造成错误,因为每个页面都需要授权。
为 AccountController 添加 [AllowAnonymous] 特性,启动匿名访问,再次运行项目,查看结果
结果就是重定向到了 Forbidden.cshtml 页面
使用角色授权
在 HomeController 上添加 [Authorize(Roles = "Administrator")] 特性
在模拟登陆处( Unauthorized方法中 )添加角色说明的身份信息条目:
claims.Add(new Claim(ClaimTypes.Role, "Administrator", ClaimValueTypes.String, "https://www.cnblogs.com/rohelm"));
运行项目查看结果
可以使用中你会发现Asp.net Core安全验证方面较以往的版本最大的改变就是全部采用中间件的方式进行验证授权,并很好的使用了Policy (策略)这个概念,下那么继续~。
基于声明的授权
返回Startup.cs,修改 services.AddAuthorization() 方法如下:
services.AddAuthorization(options => { options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber")); });
修改HomeController上的特性,添加 [Authorize(Policy = "EmployeeOnly")]
运行项目查看结果,发现被拒绝了
在模拟登陆处 Unauthorize方法添加:
claims.Add(new Claim("EmployeeNumber", "123456", ClaimValueTypes.String, "http://www.cnblogs.com/rohelm"));
goto 3.
多重策略的应用,与之前的版本几乎一样,例如本次修改的结果可以为:
详情请参阅:https://docs.asp.net/en/latest/security/authorization/claims.html的说明
自定义授权策略
自定义授权策略的实现,包括实现一个 IAuthorizationRequirement 的Requirement,和实现 AuthorizationHandler<TRequirement> 的处理器,这里使用文档
https://docs.asp.net/en/latest/security/authorization/policies.html中的Code。
添加 MinimumAgeHandler 处理器实现
在 AddAuthorization 中添加一个名为Over21的策略
options.AddPolicy("Over21", policy => policy.Requirements.Add(new MinimumAgeRequirement(21)));
在HomeController上应用该策略 [Authorize(Policy = "Over21")]
在 Unauthorized 函数中添加对应的声明信息条目 claims.Add(new Claim(ClaimTypes.DateOfBirth, "1900-01-01", ClaimValueTypes.Date));
修改时间(例如小于21岁的生日,2000-01-01)并运行调试,查看结果
对一个Requirement应用多个处理器
tip:上面的演示,我们使用了一个同时实现AuthorizationHandler<MinimumAgeRequirement>, IAuthorizationRequirement的MinimumAgeRequirement来做演示,但是如果一个Requirement徐要实现多个处理器就需要分开写了,原因很简单,这里无法实现类的多重继承。
下面我们实现一个使用Token登陆的需求
添加一个LoginRequirement的需求
public class LoginRequirement: IAuthorizationRequirement { }
添加一个使用用户名密码登陆的处理器
在一些场景中我们也会使用发放访问令牌的方式让用户登陆
在 AddAuthorization 中添加一个名为CanLogin的策略
options.AddPolicy("CanLogin", policy => policy.Requirements.Add(new LoginRequirement()));
注册自定义策略
services.AddSingleton<IAuthorizationHandler, HasPasswordHandler>(); services.AddSingleton<IAuthorizationHandler, HasAccessTokenHandler>();
在Unauthorized 函数中添加对应的声明信息条目
claims.Add(new Claim("UsernameAndPassword", "123456", ClaimValueTypes.String, "http://www.cnblogs.com/rohelm"));
// 测试切换登陆声明方式
// claims.Add(new Claim("AccessToken", DateTime.Now.AddMinutes(1).ToString(), ClaimValueTypes.String, "http://www.cnblogs.com/rohelm"));在HomeController上应用该策略 [Authorize(Policy = "CanLogin")]
运行并查看结果。
基于资源的Requirements
在实际开发者中,除了基于用户的授权验证外,通过我们也会遇到针对一些资源的授权限制,例如有的人可以编辑文档,有的人只能查看文档,由此引出该话题
https://docs.asp.net/en/latest/security/authorization/resourcebased.html
定义一个Document类
public class Document { public int Id { get; set; }
public string Author { get; set; } }定义Document仓储接口
模拟实现上述接口
注册接口实现类
services.AddSingleton<IDocumentRepository, FakeDocumentRepository>();
创建一个 DocumentController 并修改为如下内容
添加对应 Index.cshtml 视图文件
添加对应的 Edit.cshtml 视图文件
@model AuthorizationForoNetCore.Modles.Document <h1>文档 #@Model.Id</h1> <h2>作者: @Model.Author</h2>
定义EditRequirement
public class EditRequirement : IAuthorizationRequirement { }
添加对应的编辑文档处理器
在 ConfigureServices() 方法中注册处理器实现
1 services.AddSingleton<IAuthorizationHandler, DocumentEditHandler>();
由于对于文档的授权服务仅仅反正在操作方法的内部,因此我们需要直接注入 IAuthorizationService 对象并在需要的Action内部直接处理
运行查看结果
在视图中进行授权
问题来了额,上面示例的视图中怎么做限制了,那就继续了
1.使用 @inject 命令注入 AuthorizationService
2.应用该上述同样策略,做简单修改
请在运行时清理Cookie,或者在试验时直接暂时禁用
之前写的一个插件,谁有时间帮升级支持下asp.net Core:https://github.com/halower/JqGridForMvc
相关文章:
原文地址:http://www.cnblogs.com/rohelm/p/Authorization.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注