ABP框架源码学习之授权逻辑
asp.net core的默认的几种授权方法参考“雨夜朦胧”的系列博客,这里要强调的是asp.net core mvc中的授权和asp.net mvc中的授权不一样,建议先看前面“雨夜朦胧”的博客。
Abp中Controller里面用到的权限验证类为:AbpMvcAuthorizeAttribute,ApplicationService里面用到的权限验证类为:AbpAuthorizeAttribute(见下图)。


AbpMvcAuthorizeAttribute和AbpAuthorizeAttribute这两个类全部继承自IAbpAuthorizeAttribute(重要!!!),下面是这两个类的源码。
namespace Abp.Authorization
{
/// <summary>
/// This attribute is used on a method of an Application Service (A class that implements <see cref="IApplicationService"/>)
/// to make that method usable only by authorized users.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class AbpAuthorizeAttribute : Attribute, IAbpAuthorizeAttribute
{
/// <summary>
/// A list of permissions to authorize.
/// </summary>
public string[] Permissions { get; } /// <summary>
/// If this property is set to true, all of the <see cref="Permissions"/> must be granted.
/// If it's false, at least one of the <see cref="Permissions"/> must be granted.
/// Default: false.
/// </summary>
public bool RequireAllPermissions { get; set; } /// <summary>
/// Creates a new instance of <see cref="AbpAuthorizeAttribute"/> class.
/// </summary>
/// <param name="permissions">A list of permissions to authorize</param>
public AbpAuthorizeAttribute(params string[] permissions)
{
Permissions = permissions;
}
}
}
namespace Abp.AspNetCore.Mvc.Authorization
{
/// <summary>
/// This attribute is used on an action of an MVC <see cref="Controller"/>
/// to make that action usable only by authorized users.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class AbpMvcAuthorizeAttribute : AuthorizeAttribute, IAbpAuthorizeAttribute
{
/// <inheritdoc/>
public string[] Permissions { get; set; } /// <inheritdoc/>
public bool RequireAllPermissions { get; set; } /// <summary>
/// Creates a new instance of <see cref="AbpMvcAuthorizeAttribute"/> class.
/// </summary>
/// <param name="permissions">A list of permissions to authorize</param>
public AbpMvcAuthorizeAttribute(params string[] permissions)
{
Permissions = permissions;
}
}
}
重点来啦!!!
namespace Abp.AspNetCore.Mvc.Authorization
{
public class AbpAuthorizationFilter : IAsyncAuthorizationFilter, ITransientDependency
{
public ILogger Logger { get; set; } private readonly IAuthorizationHelper _authorizationHelper;
private readonly IErrorInfoBuilder _errorInfoBuilder;
private readonly IEventBus _eventBus; public AbpAuthorizationFilter(
IAuthorizationHelper authorizationHelper,
IErrorInfoBuilder errorInfoBuilder,
IEventBus eventBus)
{
_authorizationHelper = authorizationHelper;
_errorInfoBuilder = errorInfoBuilder;
_eventBus = eventBus;
Logger = NullLogger.Instance;
} public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
// 判断context中是否有继承IAllowAnoymousFilter,有则跳出方法即验证成功
if (context.Filters.Any(item => item is IAllowAnonymousFilter))
{
return;
}
//判断是否是Controller,具体方法见下面第一张截图
if (!context.ActionDescriptor.IsControllerAction())
{
return;
} //TODO: Avoid using try/catch, use conditional checking
try
{
await _authorizationHelper.AuthorizeAsync(
context.ActionDescriptor.GetMethodInfo(),
context.ActionDescriptor.GetMethodInfo().DeclaringType
);
}
catch (AbpAuthorizationException ex)
{
Logger.Warn(ex.ToString(), ex); _eventBus.Trigger(this, new AbpHandledExceptionData(ex)); if (ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
{
context.Result = new ObjectResult(new AjaxResponse(_errorInfoBuilder.BuildForException(ex), true))
{
StatusCode = context.HttpContext.User.Identity.IsAuthenticated
? (int) System.Net.HttpStatusCode.Forbidden
: (int) System.Net.HttpStatusCode.Unauthorized
};
}
else
{
context.Result = new ChallengeResult();
}
}
catch (Exception ex)
{
Logger.Error(ex.ToString(), ex); _eventBus.Trigger(this, new AbpHandledExceptionData(ex)); if (ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
{
context.Result = new ObjectResult(new AjaxResponse(_errorInfoBuilder.BuildForException(ex)))
{
StatusCode = (int) System.Net.HttpStatusCode.InternalServerError
};
}
else
{
//TODO: How to return Error page?
context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.InternalServerError);
}
}
}
}
}




拓展:当我们有某个业务需要用到AOP时,但又不想使用一些第三方框架,我们就可以借鉴上面的方法,定义一个特性,然后定义一个Filter,在Filter里面判断Controller等是否使用这些特性,并且特性的属性是否符合我们的需求,最后在Startup里面AddMvc时将这个Filter添加到FilterCollection里面。例如下图,自动验证AntiforgeryToken

ABP框架源码学习之授权逻辑的更多相关文章
- ABP框架源码学习之修改默认数据库表前缀或表名称
ABP框架源码学习之修改默认数据库表前缀或表名称 1,源码 namespace Abp.Zero.EntityFramework { /// <summary> /// Extension ...
- Golang源码学习:调度逻辑(二)main goroutine的创建
接上一篇继续分析一下runtime.newproc方法. 函数签名 newproc函数的签名为 newproc(siz int32, fn *funcval) siz是传入的参数大小(不是个数):fn ...
- 集合框架源码学习之ArrayList
目录: 0-0-1. 前言 0-0-2. 集合框架知识回顾 0-0-3. ArrayList简介 0-0-4. ArrayList核心源码 0-0-5. ArrayList源码剖析 0-0-6. Ar ...
- CI框架源码学习笔记1——index.php
做php开发一年多了,陆陆续续用过tp/ci/yii框架,一直停留在只会使用的层面上,关于框架内部的结构实际上是不甚了解的.为了深入的学习,决定把CI框架的源码从头到尾的学习一下, 主要因为CI框架工 ...
- axel源码学习(0)——程序逻辑
axel简介 axel是一个命令行下的轻量级http/ftp 下载加速工具,支持多线程下载和断点续传,支持从多个镜像下载同一文件. axel的用法如下: 图 0.1 axel usage axel 粗 ...
- 集合框架源码学习之HashMap(JDK1.8)
目录: 0-1. 简介 0-2. 内部结构分析 0-2-1. JDK18之前 0-2-2. JDK18之后 0-3. LinkedList源码分析 0-3-1. 构造方法 0-3-2. put方法 0 ...
- 集合框架源码学习之LinkedList
0-1. 简介 0-2. 内部结构分析 0-3. LinkedList源码分析 0-3-1. 构造方法 0-3-2. 添加add方法 0-3-3. 根据位置取数据的方法 0-3-4. 根据对象得到索引 ...
- CI框架源码学习笔记7——Utf8.php
愉快的清明节假期结束了,继续回到CI框架学习.这一节我们来看看Utf8.php文件,它主要是用来做utf8编码,废话不多说,上代码. class CI_Utf8 { /** * Class const ...
- CI框架源码学习笔记2——Common.php
上一节我们最后说到了CodeIgniter.php,可是这一节的标题是Common.php,有的朋友可能会觉得很奇怪.事实上,CodeIgniter.php其实包含了ci框架启动的整个流程. 里面引入 ...
随机推荐
- maven pom.xml 详细
一.什么是POM Project Object Model,项目对象模型.通过xml格式保存的pom.xml文件.作用类似ant的build.xml文件,功能更强大.该文件用于管理:源代码.配置文件. ...
- Java泛型范例
class Point<T>{ // 此处可以随便写标识符号,T是type的简称 private T var ; // var的类型由T指定,即:由外部指定 public T getVar ...
- mysql 中文乱码
- C#总结(四)调用C++动态库
由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序.在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题.最近一直在和C++ 打交道,C# 怎么调用C+ ...
- junit测试延伸--方法的重复测试
在实际编码测试中,我们有的时候需要对一个方法进行多次测试,那么怎么办呢?这个问题和测试套件解决的方案一样,我们总不能不停的去右键run as,那怎么办呢?还好伟大的junit帮我们想到了. OK,现在 ...
- JAVA学习,是一条漫长的道路
我在Java 1.0正式问世前就开始学习Java,这么多年过去了,到现在我的Java学习历程还没有停过.我阅读原文书,研究原始码,撰写程序,自认为走得扎实,不奢望一步登天.像我这样老式的学习方式,显然 ...
- HSSF、XSSF和SXSSF区别以及Excel导出优化
之前有写过运用POI的HSSF方式导出数据到Excel(见:springMVC中使用POI方式导出excel至客户端.服务器实例),但这种方式当数据量大到一定程度时容易出现内存溢出等问题. 首先,PO ...
- git clone代码时候出现的报错
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px "Andale Mono"; color: #28fe14; backgr ...
- web.xml 中<context-param>与<init-param>的区别与作用
<context-param>的作用: web.xml的配置中<context-param>配置作用 1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件 ...
- Android原生代码与html5交互
一.首先是网页端,这个就是一些简单的标签语言和JS函数: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN&q ...