使用协议转换 - 防御提示
2009-02-09 13:52:49 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁诡垎鍐f寖闂佺娅曢幑鍥灳閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡欏嚬缂併劎绮妵鍕箳鐎n亞浠鹃梺闈涙搐鐎氫即鐛崶顒夋晬婵絾瀵ч幑鍥蓟閻斿摜鐟归柛顭戝枛椤牆顪冮妶搴′簼缂侇喗鎸搁悾鐑藉础閻愬秵妫冮崺鈧い鎺戝瀹撲礁鈹戦悩鎻掝伀缁惧彞绮欓弻娑氫沪閹规劕顥濋梺閫炲苯澧伴柟铏崌閿濈偛鈹戠€n€晠鏌嶆潪鎷屽厡闁汇倕鎳愮槐鎾存媴閸撴彃鍓卞銈嗗灦閻熲晛鐣烽妷褉鍋撻敐搴℃灍闁绘挻娲橀妵鍕箛闂堟稐绨肩紓浣藉煐濮樸劎妲愰幘璇茬闁冲搫鍊婚ˇ鏉库攽椤旂》宸ユい顓炲槻閻g兘骞掗幋鏃€鐎婚梺瑙勬儗閸樺€熲叺婵犵數濮烽弫鍛婃叏椤撱垹纾婚柟鍓х帛閳锋垶銇勯幒鍡椾壕缂備礁顦遍弫濠氱嵁閸℃稒鍊烽柛婵嗗椤旀劕鈹戦悜鍥╃У闁告挻鐟︽穱濠囨嚃閳哄啰锛滈梺褰掑亰閸欏骸鈻撳⿰鍫熺厸閻忕偟纭堕崑鎾诲箛娴e憡鍊梺纭呭亹鐞涖儵鍩€椤掑啫鐨洪柡浣圭墪閳规垿鎮欓弶鎴犱桓闂佸湱枪閹芥粎鍒掗弮鍫熷仺缂佸顕抽敃鍌涚厱闁哄洢鍔岄悘鐘绘煕閹般劌浜惧┑锛勫亼閸婃牠宕濋敃鈧…鍧楀焵椤掍胶绠剧€光偓婵犱線鍋楀┑顔硷龚濞咃絿妲愰幒鎳崇喓鎷犻懠鑸垫毐闂傚倷鑳舵灙婵炲鍏樺顐ゆ嫚瀹割喖娈ㄦ繝鐢靛У绾板秹寮查幓鎺濈唵閻犺櫣灏ㄥ銉р偓瑙勬尭濡繂顫忛搹鍦<婵☆垰鎼~宥囩磽娴i鍔嶉柟绋垮暱閻g兘骞嬮敃鈧粻濠氭偣閸パ冪骇鐎规挸绉撮—鍐Χ閸℃ê闉嶇紓浣割儐閸ㄥ墎绮嬪澶嬪€锋い鎺嶇瀵灝鈹戦埥鍡楃仯闁告鍕洸濡わ絽鍟崐鍨叏濡厧浜鹃悗姘炬嫹

内核对象和 ACL
需要牢记的另一件关于 Windows 内核对象的事情是:每一个内核对象都使用访问控制列表 (ACL)(包括您要发送回的令牌)来确保安全性。从技术角度看,由于您要将句柄复制回给调用方,只要调用方能够使用这个特定句柄,ACL 就应当无关紧要。但是,调整令牌中的 ACL 以确保调用方的安全主体有使用令牌的权限不失为明智之举,特别是,考虑到调用方可能要使用 .NET 包装(如 WindowsIdentity)来操作令牌句柄。最终结果可能是拒绝调用方拥有使用您提供给他的令牌的权限。
遗憾的是,.NET Framework 还没有提供一个允许您直接操作令牌的类。WindowsIdentity 是目前框架中最接近 Token 类的类。不过,我借此机会将 System.Security.AccessControl 中的类进行了扩展以支持在令牌中读取和写入 ACL。我记得以前曾经对此进行过介绍,不过我仍然要对开发 AccessControl 命名空间的 Windows 团队成员表示感谢。扩展他们的 NativeObjectSecurity 来支持令牌出奇的容易方便。图 2 显示了我是如何实现 TokenSecurity 的。(本专栏的下载内容中提供了完整的代码。)乍一看可能代码很多,但如果仔细查看,您会发现所有代码要做的都是为令牌自定义 ACL。其中最让人感兴趣的代码是 TokenRights 枚举;而所有其他代码都是程式化的内容。
Figure2扩展 AccessControl 以支持令牌安全
public enum TokenRights : int {
AssignPrimary = 0x0001,
Duplicate = 0x0002,
Impersonate = 0x0004,
Query = 0x0008,
QuerySource = 0x0010,
AdjustPrivileges = 0x0020,
AdjustGroups = 0x0040,
AdjustDefault = 0x0080,
AdjustSessionId = 0x0100,
Read = 0x00020008,
Write = 0x000200E0,
Execute = 0x00020000,
All = 0x000F00FF, // TOKEN_ALL_ACCESS_P
AllPlusSessionId= 0x000F01FF, // TOKEN_ALL_ACCESS
MaximumAllowed = 0x02000000,
AccessSystemSecurity = 0x01000000,
}
public class TokenAccessRule : AccessRule {
public TokenAccessRule(IdentityReference identity,
TokenRights tokenRights, AccessControlType aceType)
: base(identity, (int)tokenRights,
false, InheritanceFlags.None,
PropagationFlags.None, aceType) {
}
public TokenRights TokenRights {
get { return (TokenRights)base.AccessMask; }
}
}
public class TokenAuditRule : AuditRule {
public TokenAuditRule(IdentityReference identity,
TokenRights tokenRights, AuditFlags auditFlags)
: base(identity, (int)tokenRights,
false, InheritanceFlags.None,
PropagationFlags.None, auditFlags) {
}
public TokenRights TokenRights {
get { return (TokenRights)base.AccessMask; }
}
}
public class TokenSecurity : NativeObjectSecurity {
public TokenSecurity()
: base(false, ResourceType.KernelObject) {
}
public TokenSecurity(SafeTokenHandle token)
: this(token,
AccessControlSections.Owner |
AccessControlSections.Group |
AccessControlSections.Access) {
}
public TokenSecurity(SafeTokenHandle token,
AccessControlSections includeSections)
: base(false, ResourceType.KernelObject,
token, includeSections) {
}
public override Type AccessRightType {
get { return typeof(TokenRights); }
}
public override Type AccessRuleType {
get { return typeof(TokenAccessRule); }
}
public override Type AuditRuleType {
get { return typeof(TokenAuditRule); }
}
public override AccessRule AccessRuleFactory(
IdentityReference identity, int accessMask,
bool isInherited, InheritanceFlags inheritanceFlags,
PropagationFlags propagationFlags,
AccessControlType aceType) {
return new TokenAccessRule(identity,
(TokenRights)accessMask, aceType);
}
public override AuditRule AuditRuleFactory(
IdentityReference identity, int accessMask,
bool isInherited, InheritanceFlags inheritanceFlags,
PropagationFlags propagationFlags, AuditFlags auditFlags) {
return new TokenAuditRule(identity,
(TokenRights)accessMask, auditFlags);
}
public void AddAccessRule(TokenAccessRule rule) {
base.AddAccessRule(rule);
}
public void AddAuditRule(TokenAuditRule rule) {
base.AddAuditRule(rule);
}
public void Persist(SafeTokenHandle token,
AccessControlSections includeSections) {
base.Persist(token, includeSections);
}
}
登录服务的实现如图 3 所示。您可能需要注意的首要问题是 System.EnterpriseServices 属性,这些属性为 COM+ 目录中的宿主准备了 LogonService 程序集和类。您应当特别关注需要对调用方进行验证以及需要让调用方以特定角色调用登录服务的安全属性。(我使用了称为 ProtocolTransitionUsers 的角色,并确保在部署登录服务并在 COM+ 目录中对服务进行配置时,运行我的网关所使用的安全主体是此角色的一个成员。)
更多精彩
赞助商链接