前两天,当我还在老家收拾行旅,准备回广州,为IT连的创业再战365天时,html
有网友扣上问:Taurus.MVC中如何实现认证和权限控制,最好能作个小例子。git
我一不当心回了句:等回广州我再写篇文章......github
而后,今天就来补文章了〜〜〜〜web
写文以前,又提早花了点时间,把Nuget的Package升级了一下,和源码版本作了下同步。json
一般源码的版本都会比Nuget包的靠前一个小版本:后端
目前:Taurus.MVC 升级到:V2.2.3.4 (CYQ.Data 同步升级到:V5.7.8.3)api
最近版本的更新内容:跨域
V2.2.3.1(2017-05-15) 1:增长CheckFormat方法【支持参数为空或正则验证】 V2.2.3.3(2017-06-16) 1:增长方法参数的支持(兼容常规webapi的使用方法) 2:CYQ.Data同时升级到V5.7.7.4 V2.2.3.4(2017-07-05,2017-10-22) 1 :加强跨域支持 2:修正Query<T>(aaa,defaultValue)的默认取的取值顺序问题。 3:增长EndInvode事件和BenginInvode的事件执行顺序调整。 4:CYQ.Data同时升级到V5.7.8.3
好比对于如下请求:安全
itlinks.cn/user?uid=666 itlinks.cn/user/uid/666
常规获取参数:框架
public void Get() { int uid = Query<int>("uid"); }
兼容性写法:
public void Get(int uid) { }
同时,兼容参数还能够很复杂,好比这种:
public void GetData(List<AB> unList,string a,int? b,AB ab) { Write("your data A:" + unList[0].A+" your data B:" + unList[0].B, true); }
传递对应的Post的Json多是这样的(手打的,就省了双引号了):
{ uiList:[{a:1,b:1} , {a:2,b:2}] ,a:1 ,b:2 ,ab:{a:3,b:3}}
先看:IT连的后端WebApi解决方案:
再说:解决方案的建立步骤:
即上图的:ITLinks.API ,WebAPI不须要界面,该应用程序用于存放各类Controller便可。
Nuget包管理会自动在Web.Config中加入如下相关配置。
须要把:key=“Taurus.Controllers” 项的值:改为控制器存放的项目名称(通常名称和最终生成的dll同名)。
Taurus.MVC被引用后,仅包含两个dll,Taurus.Core和CYQ.Data。
IT连的解决方案中,对这两个dll使用了源码项目(方便于做者本人作调试或扩展功能)。
以IT连中的黑名单功能为例,控制器应继承自Taurus.Core.Controller:
(这里要注意一下构造函数,将自身this传递给逻辑类的构造函数)
namespace ITLinks.API { public class BlacklistController : Taurus.Core.Controller { BlacklistLogic blacklist; public BlacklistController() { blacklist = new BlacklistLogic(this); } /// <summary> /// 获取黑名单 /// </summary> [Token] public void GetList() { string result = blacklist.GetList(); Write(result); } [Token] public void Set() { string result = blacklist.Set(); Write(result); } } }
因Web.Config中的路由类型配置为1,即路由方式为:
/控制器名称/方法名/参数
即建立了如下两个路径请求:
/blacklist/getlist /blacklist/set
理论上来讲,在能够方法里写业务代码,并调用Write方法输出json格式的字符串即完成了。
不过,实际项目中,须要清晰一些的规划:
IT连的项目中,控制器被规划用来定义路由及权限等简单设定(不包括具体的业务代码)。
把业务代码分离到ITLinks.Logic项目中处理了:
业务逻辑类继承自:Taurus.Core.LogicBase(继承后可复用Taurus.Core.Controller中的经常使用方法,如Query<T>(xxx)获取参数)
如:IT连黑名单列表中的黑名单逻辑源码示例:
(这里要注意一下构造函数,定义继承父类接收控制器参数的构造函数方法)
对于IT连的的业务逻辑:
一部分:独立到解决方案ITLinks.CommonLogic中。
用于功能的复用(在ASP.NET Aries的管理后台和此处的WebApi中复用同一份代码)
一部分:独立到解决方案ITlinks.Aop中。
用于一些第三方的消息处理。
这些,就不细讲了~~~直接飘过!
OK,接下来,咱们将重点聚焦在权限安全认证这一块:
写此以前,又扫看了一下以前写的关于Taurus.MVC的文章,发现一共才五篇,其中:
Taurus.MVC 2.0 开源发布:WebAPI开发教程 ,步骤五:有简单提到对于权限控制这一块的处理,只是不够详尽。
本文,就以 IT连 App的后端 WebAPI 的逻辑来给大伙作进一步细致说明:
首先:对于继承自Taurus.Core.Controller的控制器,都拥有如下几个可重写的方法:
public class TestController : Taurus.Core.Controller { public override bool CheckToken() { } public override bool BeforeInvoke(string methodName) { } public override void EndInvoke(string methodName) { } }
以及三个权限相关的特性[Token]、[HttpGet]、[HttpPost]:
[Token] public class TestController : Taurus.Core.Controller { [HttpGet] public void Get() { } [HttpPost] public void Post() { } }
特性若放在类上,即对全部方法都生效!
整个的调用顺序为:
1:调用CheckToken(若是方法标识[Token]属性)【若是返回false则停止如下执行,可人工干预】 2:检测Get或Post(若是方法标识[HttpGet]或[HttpPost]属性)【若是返回false则停止如下执行,系统自动控制】 3:调用BeforeInvoke方法【若是返回false则停止如下执行,可人工干预】 4:调用咱们定义的方法,如Get或Post方法。 5:调用EndInvoke方法。
接下来,再以IT连中的请求为例讲述流程:
此时不需权限,一切正常定义,如:
public class SysController : Controller { SysLogic sysLogic = null; public SysController() { sysLogic = new SysLogic(this); } /// <summary> /// 获取配置信息 /// </summary> public void GetConfig() { string msg = sysLogic.GetConfig(); Write(msg); } /// <summary> /// App版本升级 /// </summary> public void Update() { string msg = sysLogic.CheckAppVersion(); Write(msg); } }
登录注册也不须要权限验证,方法依旧如常。
public class UserController : Controller { UserLogic user; public UserController() { user = new UserLogic(this); } public void Register() { string result = user.Register(); Write(result); } public void Login() { string result = user.Login(); Write(result); } }
不过,在登录或注册成功后,须要建立一个Token返回给App客端存档:
如何建立Token: 能够把用户的基本固定又不重要的信息串在一块儿,而后加下密就能够了; 好比:(用户ID+注册时间+用户名+有效日期)=》加密成:abfabcbcdxxabfabccdc
具体代码可参考 ASP.NET Aries 框架中的 UserAuth.cs 中的 GetAuthToken 方法
因为用户在注册或登录时,已经存档了Token在客户端,只要以后的请求,都带上这个Token便可。
好比用户获取自身的完整信息,或提交用户反馈是须要权限的:
public class FeedbackController : Controller { FeedbackLogic feedbackLogic = null; public FeedbackController() { feedbackLogic = new FeedbackLogic(this); } public override bool CheckToken() { string userid = UserAuth.UserID;//从用户传来的Token中解密获取数据 bool result = !string.IsNullOrEmpty(userid) && UserAuth.UserID.Length == 36 && UserAuth.RegTime.Length == 8; if (!result) { Write(LangConst.EC_10000, false);//返回Token验证失败 } return result; } /// <summary> /// 用户反馈建议 /// </summary> /// <returns></returns> [Token] public void Set() { string result = feedbackLogic.Set(); Write(result); } }
对于Set方法,须要基本的身份认证,加上了[Token]特性;
同时:须要在CheckToken方法写代码来检测用户带过来的Token是否合法:
1:从请求数据或请求头中获取(Token字符串) 2:解密,较验格式及是否过时。 3:根据解密的结果,来返回true或false。
具体代码仍可参考 ASP.NET Aries 框架中的 UserAuth.cs 中UserID属性是怎么被反解出来的。
这样,就完成了基本的权限认证。
鉴于检测Token合法性的代码是同样的,业务控制器可能很多,所以须要有统一的地方:
Taurus.MVC定义了三个全局的方法,位于DefaultController中,固然这个控制器文件默认是不存在的,须要本身新建:
public class DefaultController : Controller { public static bool CheckToken(IController controller, string methodName) { //将Token验证合法性的代码写在这全局的地方,对全部的Controller都生效。
string userid = UserAuth.UserID;
bool result = !string.IsNullOrEmpty(userid) && UserAuth.UserID.Length == 36 && UserAuth.RegTime.Length == 8;
if (!result)
{
controller.Write(LangConst.EC_10000, false);
}
return result;
} public static bool BeforeInvoke(IController controller, string methodName) { } public static void EndInvoke(IController controller, string methodName) { } }
DefaultController的全局方法的优先级:
这三个static方法的优先级,低于Controller自身同名的实例方法;
即若是某个Controller已经重写了CheckToken实例方法,则全局的CheckToken不会被调 用,其它两个方法亦同。
DefaultController是Taurus.MVC的特殊的控制器,其特殊在:
1:当寻找的控制器不存在时,都会定位到DefaultController中寻找,若是DefaultController也没有,则抛出异常。 2:若是方法在DefaultController中找不到时,则会调用Default方法(Taurus.Core.Controller有默认Default方法,可被重写)。
3:三个全局的统一方法,被命运安排在这里。
你值的拥有!
接下来又得把线程切回去继续写IT连创业系列、以及IOS的Sagit.Framework开发框架系列了!