《设计模式--基于C#的工程化实现及扩展》补充 Security Design Pattern 系列 1 公钥体系与分布式环境要求

公钥体系与分布式环境要求

王翔 (Vision Wang)

2009-02-10

概要

作为《设计模式--基于C#的工程化实现及扩展》第一版的延续,计划陆续推出信息安全设计模式(Security Design Patterns)系列,集成模式(Integration Pattern)、数据模式(Data Pattern)、数据访问模式(Data Access Pattern)、XML应用模式(XML Pattern)以及随着Web 2.0出现的用户体验模式(UX Pattern: User Experience Pattern)由于国内社区已经有不少现成的资料,因此暂时延后推出。

作信息安全的同行往往强调“三分技术、七分管理”,管理非常重要,尤其是对人员的管理、培训、教育更加如此,不过本系列着重在那“三分”,而且仅仅是“三分”中涉及到应用开发、设计的部分。

正如我们在《设计模式--基于C#的工程化实现及扩展》GOF23经典部分介绍的那样,GOF23中绝大部分模式给开发人员的感觉往往集中在解决类型关系上,大量的实例也主要针对一个“系统”/“子系统”内部的变化关系上,但随着内容的展开,我们发现很多模式也被广泛应用于分布式系统中,成为架构模式的关键部分,例如:代理模式(Proxy Pattern)、观察者模式(Observer Pattern)、外观模式(Façade Pattern),同样在完成常见信息安全开发方面我们也有很多类似的变化要处理,由于专门针对该领域的开发人员数量相对较小,即便在项目组内部往往也是“少数派”,因此信息安全设计模式并不像设计模式GOF23及其它分支发展脉络那么清晰,但经过软件行业几十年积累也有些“套路”可循,尤其针对开发中常见的认证、授权、访问控制已经有一些模式方法,本系列主要针对这些内容结合自身项目经验介绍。

信息安全模式自身面临的主要问题

信息安全系统/子系统首先是个信息系统/子系统,因此它与GOF23设计模式中描述的内容有共通处,其思想一样可以用于解决信息安全系统/子系统相应的变化问题。区别于设计模式的其他分支关于变化的控制需求,信息安全模式首先要解决一个问题——信任

也就是说无论我们提供何种信息安全功能/服务,总要基于一个相对可信的环境,比如:我们验证用户密码,但用户凭证信息保存的这个库往往首先由认证程序假定是可信的,否则其他都免谈了。项目中,随着参与方的不断增多(用户、软件、系统、服务、信息源…),我们必须提供一套大家都认为可信赖的环境,那么这种分布是公共信任环境与我们经常“手口相传”的信任体系有什么区别呢?

前者,我们经常用对称密钥,而后者往往还需要借助证书为凭证的非对称密钥体系,然后借助一些公共信任的机制/服务,形成一套以公钥为基础的环境。

(对于“对称密钥”、“ 非对称密钥”的概念,请参考密码学教材,一般都有较为详细的说明)

另一个关键因素就是“控制隔离”,参考其他设计原则的描述方法,我们不妨暂称之为——Control Isolation,也就是说当你想控制某个对象/服务访问另一个对象/服务的时候,为了体现控制往往要借助一个第三方对象/服务把两者隔开。

图01-01:通过控制隔离关系实现信息安全控制

这其中我们不难发现,GOF23部分的结构型模式中的代理模式、外观模式以及构造型模式中的工厂方法(/抽象工厂方法)单独个体都难于满足这里的需要。因此从某种程度看,由于信息安全开发中对象角色的复杂性,实际项目中安全模式往往需要组合多种手段才可以较有效的隔离变化。

信息安全模式中的价值因素

区别于GOF23中大部分变化要求,信息安全模式还有一个明显的特征就是他的价值因素,以桥模式(Bridge Pattern)为例,我们在《设计模式--基于C#的工程化实现及扩展》的章节中提到,之所以称之为“桥”,是因为它把客户程序可能导致变化的对多个因素变成依赖一个抽象的“桥板”,而每个变化对象的实现类型则被作为桥墩。

图 01-02:桥模式解决多因素变化的思路

通过这个过程,如果出现更多维度变化的情况,我们可以统一用一套模式思路解决相关问题。

而在信息安全开发的一个典型操作——“授权”中我们却不能简单的提供一个解决方案,其中一个关键考虑就是不同对象实体的价值因素,例如,典型的授权方式如下:

l Role Based Security:适合我们常规的业务性系统;

l Identity Based Security:适合高安全等级,需要精细颗粒度控制用户访问的系统,例如:审计系统;

l Claims Based Security:适合对于不确定的环境部署的应用,安全性依据客户端提交访问时声明的内容进行检查;

l Resource Based Security:以目标资源为中心的系统,主要针对敏感资源的控制;

从功能上,上面4种受权方式都是为了实现“用户访问功能进而操作某些资源”的过程,但设计上抽象过程不同:

Role Based Security方式:

       Identity Based Security方式:

       Claims Based Security方式:

       Resource Based Security方式:

同一个过程形成多种依赖关系,主因是什么呢?关键在于我们认为谁的价值更大,更需要保护。因此,信息安全模式的使用上,我们分析的要点除了以前“隔离变化”外,还需要基于风险分析评估其中资产(及控制资产对象)的价值。

信息安全模式的AOP特征

AOP(Aspect-Oriented Programming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。OOP允许定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

而AOP技术则恰恰相反,它利用一种称为“横切”的技术,渗透到封装的对象内部,并将那些影响了多个类的公共行为封装到一组可复用模块中——“Aspect”(即方面)。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,有利于未来的可操作性和可维护性。

图 01-03:AOP的加载机制

在《设计模式--基于C#的工程化实现及扩展》的《装饰模式》部分我们介绍了基于.NET的三种AOP实现机制,但并没有展开,不过普遍作为非业务逻辑主干的控制机制,面对如此众多的安全需求,如果将安全特性与业务逻辑、业务流程混编在一起,将带来代码逻辑的复杂性,使之难与维护,尤其在需求变更的情况下将增加开发、测试和部署人员的劳动成本。为此,需要变换设计思路,采用AOP(或依赖注入等)思想设计应用,将各种模式化处理措施以较低的耦合度“编织”(Weaving)到应用中,但又不影响应用逻辑和应用流程本身。

信息安全的主要领域

如上文,尽管该系列近关注于“三分”,但由于信息安全领域分支的增加,从覆盖内容看信息安全模式服务的内容主要包括下列领域:

消息或传输通道安全性

传输通道安全性相对实现比较简便,可以保证应用各组成、应用间的交互在一个安全的外壳内实现,但存在一定限制:

l 如果仅设计点对点的安全性,那么在企业应用服务化的背景下,必须配合一个第三方的公钥机制(例如:NTLM、Kerberos、Active Directory …)提供安全性,否则随着应用的增加,点对点间的安全性维护成本将平方级增加;

l 难于实现带中转的路由机制;

如果将安全性设计为消息(Message)级,虽然需要在应用层面增加部分开发或配置的工作量,但可以获得如下好处:

l 安全性与通道无关,尤其适于无安全保证的传输通道;

l 适于异构应用间传递;

l 尤其适合需经过多次路由或持久化的分布式长事务服务调用;

由于关注重点的不同,两类安全性普遍应用的模式也有所不同。

认证

主要包括:

l 用户信息存储。例如:采用自己的用户库还是使用LDAP系统统一的人员信息;

l 岗位或角色存储。例如:采用自定义的角色表还是通过企业统一授权平台的SOAP调用获得;

l 调用方式:是per Call调用还是一次性认证后缓存?是每个应用独立完成还是基于SSO?

另外,对于企业内网项目,还需要考虑下列内容:

l 是否可以采用SQL Server、ORACLE作为Membership Provider?

l 是否采用Active Directory、Kerberos认证;

l 是否需要用证书或者IC卡、USBKey进行认证;

对于企业互联网项目,还必须仔细考虑用户信息凭证及其载体的问题。

授权

根据不同安全等级的要求,认证和授权还需要定义不同的安全实施策略,甚至混合使用不同的策略,例如上文提到的:

l Role Based Security;

l Identity Based Security;

l Claims Based Security;

l Resource Based Security;

审计和日志系统

虽然根据应用等级保护的要求,各企业开发的应用逐步将审计和日志列入常规开发内容,但项目实施上除了应用自己完成相关功能外,还可以借助开发平台、所集成产品的特点完成,例如:

l 在WCF、ASP.NET应用中,通过配置指定是否对过路信息进行记录、记录的详细程度;

l 针对WMI事件,结合企业安全运行管理平台进行面向业务连续性的事件建模;

异常管理

相对而言,大部分企业现有运行系统对于应用异常的管理属于弱项,大部分应用反馈的异常都是未经包装的内容,而且往往泄漏过多技术细节;但如果封装的内容过于肤浅,又不利于提供现场技术支持(即Supportability不好)。为此,设计中开发人员需要定义policy为整个应用程序各层的异常处理创建一致的策略,同时提供下列三种Handler(处理程序):

l Wrap handler:包装一个原始异常在另一个新异常之内,并且原始的异常对象将保留在InnerException属性中;

l Replace handler:替换一个异常为另一个异常;

l Logging handler:异常处理程序首先格式化异常信息,如消息和Stack trace,接着Logging handler将异常内容记录下来;

代理和委托

由于程序的分布性,为了减少企业系统管理人员的工作量,开发中往往需要设置代理账号或者定义账号委托关系的方式完成应用设计。

图 01-04:账号与委托账号示意

这两个特性在企业业务国际化、区域化的背景下显得更为重要,越来越多的业务打破现有边界,为此功能授权除了要说明用户自己可以完成哪些功能外,还需要借助代理及委托说明他完成什么范围内以“谁 ”的名义完成这些功能。除了简单的委托之外,企业环境下往往还需要对于委托及代理的方向性进行限制,同时针对待访问资源的属地关系增加必要的审批手段。

报文、消息及参数检查

很多情况下,应用的安全威胁来自交互过程,情节轻的可能会影响业务处理的有效性,严重的可能导致非法用户获得超级管理权限,威胁企业联网信息系统及网络的安全。例如:

l 如果不加限制,用户可能会输入任何格式的编号,可能越界访问到其他区域信息;

l 对于ASP.NET应用,如果不对提交的QueryString或Form的内容进行检查,可能导致SQL注入式攻击;

为此,应用需要对报文、消息以及调用参数进行必要的检查,否则不能“放行”进入企业的信息系统。

信息安全模式的应用特点

与上述信息安全领域有所不同,信息安全模式由于其是设计思想,因此采用的是面向对象设计配合案例法的方式,包括:

l 采用面向对象的模型方法分析授权、认证等信息安全过程;

l 抽象关联因素,引导信息安全模式的思路同样是实现“依赖于抽象而非具体”;

l 将企业的各种规范借助面向对象建模中的约束条件表现出来;

这样,信息安全模式与我们在GOF23部分的设计基础完成统一,因此我们可以用类似的方式用Security Design Pattern的思想分析各类信息中相关领域中重复出现问题及“常规解”。

在经典《设计模式》中我们已经习惯模式介绍的常规体例:

l Intent

l Motivation

l Applicability

l Structure

l Participants

l Collaborations

l Consequences

l Implementation

l Known Uses

l Related Patterns

本系列为了介绍清晰、简便,采用下列体例介绍:

l Motivation、Problem、Forces:说明情景、面临的问题以及各种限制因素;

l Solution:分析、设计并获得“常规解”的过程,包括明确参与方、协作、执行时续的过程;

l Implementation、Sequences:采用C#和.NET平台提供一个标准实现,而且沿用《设计模式--基于C#的工程化实现及扩展》解决问题的思路,力图提供一个更贴近实际项目的实现案例。如果您的平台是Java EE、动态语言也可以参考类似的实现思路;

l Related Patterns:分析该模式与其他模式(并不限于信息安全模式)的关系;

l Known Uses及Known Non-Security Users:主要提供行业内典型产品的应用案例分析,此外还专门提供一些尽管用到该模式,但结果并没起到“安全”结果的案例。

信息安全模式中的反模式

此外,就如有很多Anti Pattern一样,信息安全领域的设计模式同样也存在很多典型的Anti Security Design Pattern。下面我们举一个例子:

Motivation、Problem、Forces

企业应用中一般都需要对用户的身份进行检查,完成确认后我们才允许用户执行后续操作。虽然典型处理上,我们可以部署PKI环境,先为应用安置一个安全的“窝”,但考虑到业务上线时间我们决定采用项目自行开发的方式。

其中一些约束因素如下:

l 项目采用Smart Client方式;

l 由于企业用户比较多、分布比较广,但企业现有认证框架集中在总部信息中心,因此如何提高认证效率成为应用的一个关键指标;

l 由于企业门户登录后需要经常登录不同的功能,而如果每次都要登录不同功能需要较长的网络往复,用户体验很差,即便采用AJAX用户也已经对“旋转小圈”失去新鲜感;

Solution

参考我们在《设计模式--基于C#的工程化实现及扩展》结构型模式的介绍,在客户端引入Authentication Cache Proxy,设计上只在第一次调用的过程中把用户IIdentity在不同应用进行认证后,缓存到客户端的内存中,后续调用全部基于该内存的认证情况进行检查。

静态结构

图01-05:增加认证缓冲后的认证代理结构

(其中Subject的内容就是负责认证并反馈认证信息)

执行时序

相应的执行时序如下:

图01-06:增加认证缓冲后认证代理的执行时序

分析

上面的设计虽然从性能、隔离变化两个方面较好的解决了认证问题,但从信息安全角度看是个典型的“自欺欺人”的做法,因为其他程序可以很容易通过多种手段修改客户端内存这个没有实施任何保护的缓存,甚至于借助通道sniffer等方式可以很容易借助“重发”手段模式这个认证后的调用,因此这个假设的“Local Cahced Proxy”模式本身虽然从设计模式角度不是Anti Pattern,但如果落实到安全领域而言他就是一个Anti Pattern。

那么您可能会说“没有绝对安全”,确实,而且实际项目中我们也确实经常需要组合使用多种模式,但如果一个“套路”在某个Context下看可行甚至完美的解决了问题,但实际上从信息安全角度看他实际上很容易破坏这个“套路”所服务的领域目标的话,那么我们常常可以将这个迷惑的错误“套路”定义为一个Anti Idiom/Pattern。

信息安全模式的继承关系

以授权为例,众多授权功能本身就已经形成“套路”,本身就是个Authorization Pattern家族,还原授权的本原,最基本的Authorization Pattern其结构如下:

图01-07:Authorization Pattern的静态结构

但我们在实际项目中往往发现同一个工作岗位的用户他所具有的访问权限很类似,甚至企业对于业务权限的规定大部分就是针对岗位而非用户个人,因此授权模式可以进一步扩展为大家熟悉的“基于角色的安全性”( RBAC:Role-Based Access Control),这个“套路”模式本身也变化为 RBAC Pattern,它的静态结构如下:

图01-08:RBAC Pattern的静态结构

如我们上文介绍的内容,这里的Role就是为了提供进一步安全手段增加的控制措施。响应的两个模式间的关系也可以体现为典型的继承特点:

图01-08:授权模式间的继承关系

其他

后续,本系列将结合上面提到的“信息安全领域”展开一系列信息安全模式的介绍。

 

关于《设计模式——基于C#的工程化实现及扩展》书签

关于《设计模式——基于C#的工程化实现及扩展》封面

关于《设计模式——基于C#的工程化实现与扩展》电子书、示例代码发布,互动网预订开始

关于《设计模式——基于C#的工程化实现及扩展》定价修改

关于“我的第一次策划实践”

关于我的第一次策划实践——初入目录分析之门

帮你造就有弹性、能扩充、易维护的软件实体

“王翔——设计模式C#工程化实现”在线讲座资料下载

《设计模式》的表达模式

 

围炉取暖话“创业&升职”,请看《走出软件作坊》;

围炉取暖话“求职&面试”,请看《编程之美——微软技术面试心得

posted @ 2009-02-11 17:11  Chinaren  阅读(227)  评论(0编辑  收藏  举报