基于C#注解构建Web API安全模型

2017-09-15 05:09刘子龙
课程教育研究·上 2017年30期
关键词:访问控制

刘子龙

【摘要】随着Web技术发展,Web API驱动开发已成为Web应用的关键部分。Web API成为了云服务最核心的要素,同时其安全性也得到了前所未有的關注,本文提出了一种基于C#注解构建的Web API安全模型,很好地满足了Web安全性需求。

【关键词】C# Web API 访问控制 Web安全

【中图分类号】G202 【文献标识码】A 【文章编号】2095-3089(2017)30-0207-02

Web技术已经越来越流行和深入,云计算带动了云服务的成长,很多IT巨头都提供了各种各样的云平台,如百度云提供了百度语音识别API,通过简单的调用即可实现语音识别。随着社会分工的细化和专业化程度的提高,Web API服务模式越来越流行,不同厂商依靠自己擅长的领域提供更为专业和深度的Web API服务,每个个体均可以通过Web API完成凭一己之力不可能完成的任务,故Web API自身安全显得尤为重要。

一、安全漏洞

就软件层面来说,攻击常见手段如下:

·高频率大数量的机器人请求

用机器人来不停进行请求,导致服务器资源紧张或充斥了大量垃圾数据,服务器不堪重负就有可能宕机。

·CSRF,跨站请求伪造

攻击者盗用了用户身份,以其名义发送恶意请求,比如用户在网站A登录后,跳转到一个非法的网站B,网站B引导用户填入一些敏感信息后反过来提交给网站A,极有可能盗取用户的信息或进行非法操作。

·SQL、脚本注入,getshell

在网站的表单提交中,嵌入一些非法脚本,就有可能导致网站关键信息泄露。

·非法请求暴露的API接口

Web API一般提供详细的API接口说明文档,如自身安全防范不到位,攻击者很容易通过技术手段进行非法API接口调用。

二、防范手段

针对上述常见手段,本文首先从防范手段入手,提出了下列方式:

·基于 POST 方式

Web 提交分为 GET、POST 两种形式,其中 GET 体现为 query string(查询字符串),这个字符串会显示在地址栏上面,极为不完全,为避免这种低级安全问题,所有 Web API 均采用 POST 方式提交。

·基于服务器脚本

客户端脚本是可以看得到源码的,而且极易被篡改,而服务器脚本是部署在服务器端,并且基本上是编译后部署的,安全性大大增强,并且,只有网站拥有者才有权限修改,如微信公众号的 API 均要求采用服务器端程序访问。

·基于 RBAC 限制

RBAC 是基于角色的访问控制,Web API 大部分接口是需要特定的角色才能访问的,访问者请求一个没有权限的接口是无法成功的,这就能在业务逻辑层将恶意攻击阻止。

·统一访问令牌

CSRF,跨站访问是常见的攻击手段,但如果在每次提交时就发回一个服务器植入的访问令牌,并校验令牌是否统一,就可以很好的杜绝 CSRF 攻击。

·频次、数量限制

对于一些公开 API,恶意攻击者采用大量肉机实施高频次不间断的数据请求,导致服务器压力过大而宕机,如果对频次和数量进行限制,则此类问题可以避免。

·基于 OAuth 2.0

OAuth 2.0 是一个与授权相关的国际通行标准,作为 Web API 提供商首先要对开发者做认证,认证完成后进行接口访问,访问前获取一个访问令牌,通过访问令牌访问对应的接口,这几组动作完成后,安全性可以得到保障。

三、注解模型

通过上述防范手段的设定,本文提出了基于C#注解模型的实现。

C#注解是通过Attribute类来实现,它可以对类、方法、属性进行注解,此种做法在某些实现逻辑上更为简洁和方便,比如某个属性是数据库表的主键,通过下面代码即可表明:

[Key]

public int UserId;

可见,采用传统语法是很难做到上述功能的。

Web API安全的注解主体为 AllowCall,参数按功能划分如下:

·IsNeedLogin

是否需要登录,默认为 false。下例表明 ResetPassWord 需要登录才能访问。

[AllowCall(NeedLogin=true)]

public void ResetPassWord(int userId,string oldPassWord,string newPassWord)

·IsSuperAdmin

是否需要超管,默认为 false。

·RolePath

允许哪种角色访问。下例表明 Delete 需要 /BeCool/Editor 角色才能访问。

[AllowCall(RolePath='/BeCool/Editor')]

public void Delete(int articleId)

·RightPath

允许哪种权限访问。

·Frequency

同一个授权应用,每秒可请求多少次,默认为 -1 表示没有限制。下例表明 GetUser 每秒可以请求 1次。

[AllowCall(Frequency=1)]

public User GetUser(int id)

·Count

可请求数量,默认为 -1 表示没有限制。下例表明 GetArticles 可以返回 1000 条。

[AllowCall(Count=1000)]

public List

GetArticles(int catalogId)

·SafetyParameterName

不允许非安全字符串,如 SQL、脚本注入。下例表明传入的 content 参数中不能包含非安全字符串。

[AllowCall(SafetyParameterName='content')]

public IM Add(string title,string content)

通过上述注解,已经可以完成大部分安全防范了。另外,本文设计的注解模型还包含如下几个能力:

·继承能力

子类可以继承父类关于安全性注解的内容,也可以将子类的注解与父类进行拼合。下例表明子类的 GetUser 覆盖了父类中 GetUser 的安全性注解。

//父类

[AllowCall(Frequency=1)]

public User GetUser(int id)

//子类

[AllowCall(Frequency=10,Count=100)]

public User GetUser(int id)

·全局常量

在注解中,可以用到一些全局常量,比如当前登录用户 Id。

·值域校验

上述全局常量经常用于值域校验。下例表明登录用户只能修改自己的密码。

[AllowCall(NeedLogin=true,VerifyParameterName='userId',VerifyValue=G.UserId)]

public void ResetPassWord(int userId,string oldPassWord,string newPassWord)

四、技术实现

上述注解模型,采用 C# 提供的Type.GetMemebers(获取类型对应成员集合)、MemberInfo.IsDefined(是否定义某个属性)和MemberInfo.GetCustomAttributes(获取特定属性集合)三个函数组合实现。

在前文中,ResetPassWord方法必须登录后才能访问,判断方式如下:

var im=new IM();

var attrs=AttributeUtils.GetCustomAttributes(typeof(UserControl),"ResetPassWord")

as AllowCallAttribute;

if(attrs.NeedLogin==true)

{

if(G.IsLogin==false)

im.Error("请先登录。");

}

return im;

为了更方便的进行防范处理,本文还提供了一套工具集,核心代码如下:

///

/// 判断某个类(typeOfClass)的某个字段(memberName)是否定义了某个属性(typeOfAttribute)

///

/// 对象类型

/// 属性类型

/// 成员名称

///

public static bool IsAttributeDefined(Type typeOfClass, Type typeOfAttribute, string memberName)

{

MemberInfo[] mis = typeOfClass.GetMembers();

for (int i = 0; i < mis.Length; i++)

if (mis[i].IsDefined(typeOfAttribute, false)

&& mis[i].Name == memberName)

return true;

return false;

}

///

/// 得到某個类(typeOfClass)的某个字段(memberName)定义的某个属性(typeOfAttribute)集合

///

/// 对象类型

/// 属性类型

/// 成员名称

///

public static object[] GetCustomAttributes(Type typeOfClass, Type typeOfAttribute, string memberName)

{

MemberInfo[] mis = typeOfClass.GetMembers();

for (int i = 0; i < mis.Length; i++)

{

if (mis[i].IsDefined(typeOfAttribute, false)

&& mis[i].Name == memberName)

{

return mis[i].GetCustomAttributes(typeOfAttribute, false);

}

}

return null;

}

限于篇幅,其他几个工具代码就不一一贴上了。

五、总结

本文通过安全漏洞的分析,提取了几个防范手段来抵御攻击,并采用 C# 注解模型来实现,大大降低了开发者工作量,提升了开发效率,简化了开发逻辑,在具体项目实施过程中取得了很好的效果。

猜你喜欢
访问控制
电力通信运维系统中基于用户可信度的访问控制
云的访问控制研究
云计算访问控制技术研究综述
基于分级保护的OA系统应用层访问控制研究
浅谈分层管控建立集团大厦内部网络权限管理
浅析数据库的安全设计与管理
校园网多层次访问控制探析
新时期校园网络安全体系构建的研究与应用
探讨企业如何实行分级授权的管理模式
校园骨干层网络交换机的访问控制技术