XML安全:使用SAML确保可移植的信任 - XML与XML Schema - TT SO...

来源:百度文库 编辑:神马文学网 时间:2024/05/23 17:46:25
XML安全:使用SAML确保可移植的信任
2009-3-24   大 |中 |小


导读:本文中将探讨可移植的信任。安全断言标记语言或者SAML是一种保证可移植信任的机制。我将从SAML背后的目标谈起,然后介绍SAML的体系结构,最后解释SAML的概念。
关键词:XML安全可移植的信任SAML安全断言标记语言
正在加载数据...
长期以来,人们认识到需要提供一种机制在不同的协作域之间传递关于实体的信息,同时域又不失去对这些信息的所有权,安全性断言标记语言或者SAML满足了这种要求。交换的信息可以是关于主题或者验证信息的断言。这种方式也称为单点登录。
在XML安全系列文章的上一篇中,我谈及了与安全有关的两个很重要的主题:
·易于管理。
·可移植的信任。
在那篇文章中,我讨论了使用XKMS实现安全基础设施的易管理性。本文中将探讨第二个主题,可移植的信任。安全断言标记语言或者SAML是一种保证可移植信任的机制。我将从SAML背后的目标谈起,然后介绍SAML的体系结构,最后解释SAML的概念。
信任不可移植的问题
您经常会遇到需要提供个人信息的Web站点,原因基本上是验证或者通过个人首选项定制站点。最终,您会发现在许多不同的地方有多个帐户。如果每个站点都为此设立自己的用户资料库,结果就会造成:
·对所有这些单独的站点都要考虑您的信息的安全。
·多个站点不能协同为您提供所感兴趣的更精细的服务。
为了进一步说明上述第二点,我提供一个很典型的例子:旅游预约。其中包括机票、旅馆和出租车的预定。您可能希望向某家航空公司、某个旅馆以及某个汽车出租商预订,但是不存在一种机制使您能够在三个独立的站点之间无缝移植——可能需要提交证明进行三次验证(假设这三家您都有帐户)。
SAML被设计成解决这一问题,它允许只有少数经过选择的团体保留您的信息,并且如果需要,在得到您的明确批准之后这些团体可以与其他有关的团体共享这些信息。这意味着,您的信息安全的掌握在您所信任的团体手中,并且可以访问一些供应商通过组织多种低层次服务所提供的高级服务。
本文将说明SAML如何实现这一目标。
SAML的目标
SAML的主要目标包括:
·建立一种独立于协议和平台的验证和授权交换机制(也称为单点登录,或者SSO)。
·应该独立部署环境,能够用于集中式的、分散式的以及联合式的部署场景。
·SAML框架应该是基于XML的。
SAML的体系结构
SAML是一种控制对已验证主体的资源进行访问的机制。对资源的访问基于特定的策略管理。这种机制需要两种关键性的活动:
·基于策略的访问控制决策。
·强制实施这些决策。
SAML提供了两种角色处理这些活动:策略决策点(Policy Decision Points,PDPs)和策略实施点(Policy Enforcement Points,PEPs)。
场景:主体希望从目标Web站点访问一些受保护的内容。主体前往能够识别或者已经验证该主体的源Web站点。用户从源站点出发尝试访问目标Web站点上的受保护内容,步骤如下:
·主体向源站点验证并请求到目标站点受保护资源的链接。
·源站点使用验证标志重定向主体。
·主体使用该标志向目标站点请求受保护的资源。
·目标站点PEP检查该PDP的权限。
·PDP可能内部请求源站点使用该标志进行SAML验证断言。
·源站点根据标志向目标站点提供SAML验证断言。
·目标站点向主体提供受保护的资源。
总之,在源站点验证的主体从SAML权威获得一个标志并将其提供给目标站点。目标站点使用该标志从源站点请求所需要的信息而不需要明确地从主体获取。
SAML综述
SAML规范由以下部分组成:
·断言与协议:该规范处理定义XML编码的断言的语法和语义,以及请求和响应协议。
·绑定与配置文件:该规范处理SAML请求/响应消息到底层通信协议如SOAP和SMTP的映射。控制在底层通信协议中嵌入和提取SAML信息的一组规则称为一个配置文件。
·一致性规范:不同的SAML实现可能只实现这些规范的一部分。一致性规范设置了一种基本标准,SAML规范的实现在能够称为一致性实现之前必须满足这一标准。这样有助于提高互操作性和兼容性。
·安全和保密的问题:该规范涉及SAML体系结构中的安全风险,具体而言就是SAML如何应对这些风险以及无法解决的风险。
我将采用问答的形式介绍和SAML有关的概念。我将逐个回答以下问题以澄清这些基本概念:
·什么是断言?
·谁生产和消费断言?
·如何请求断言,如何发送响应?基本上而言,请求和响应协议是什么?
·SAML请求响应协议可以绑定到哪些底层的通信传输 协议?
·如何向SOAP这样的底层通信传输协议中插入SAML断言?
·什么是一致性规范,为何需要它?
·如果只实现了标准的子集,也能说该实现是兼容的么?
·定义一致性的粒度级别是什么?
·基于SAML的系统的安全风险是什么?
什么是断言?
断言提供主体所执行的验证、主体属性、是否允许主体访问特定资源的授权决策等信息。
一组断言组成一个主体的配置文件。配置文件中的断言可能来自不同的组织。
断言有三种类型:
·验证:验证断言处理主体在特定时刻、特定机制下的身份验证。
·属性:属性断言提供联系特定属性与给定主体的一种机制。
·授权决策:授权决策断言管理给定主体访问资源的权限。
谁生产和消费断言?
SAML权威生产断言。SAML权威可进一步划分为验证权威、属性权威或者PDP。断言的消费者是客户或者SAML权威本身。
如何请求断言,如何发出响应?基本上而言,请求和响应协议是什么?
SAML请求响应协议为发送断言请求和获取响应定义了一种标准消息格式。SAML请求协议定义的消息格式采用下面的请求类型:
·SubjectQuery:允许使用模式定义新的查询类型,指定一个SAML主体。
·AuthenticationQuery:请求一个主体的验证信息。返回验证断言作为响应。
·AttributeQuery:请求主体的属性信息。响应中包括请求者拥有权限的那些属性的属性断言。
·AuthorizationDecisionQuery:进行授权决策。根据请求者提交的证据,该查询决定是否授权该请求者访问受保护的资源。
·AssertionIDReference:根据唯一标识符检索特定的断言。
·AssertionArtifact:根据代表断言的助诊文件检索一个断言。
响应消息格式分别对应请求的类型。
SAML请求响应协议可以绑定到哪些底层的通信传输协议?
SAML定义了SAML请求和响应消息在标准通信传输协议上的映射。目前只定义了一种绑定,SOAP上的SAML。SAML SOAP绑定描述了SAML请求和响应消息交换如何映射到SOAP消息交换上。SAML规范规定任何遵循SAML规范的实现必须实现基于HTTP的SOAP上的SAML。实现也可以选择实现基于其他传输协议系如SMTP或FTP的SOAP上的SAML。
如何向SOAP这样的底层通信传输协议中插入SAML断言?
SAML规范定义了一组称为配置文件的规则,描述了实现应该如何在底层协议消息中插入、提取和集成断言。比如,SAML的SOAP配置文件描述了如何将SAML断言添加到SOAP消息、SOAP头会受到SAML断言的什么影响,以及如何在SOAP消息中处理SAML错误。
SAML规范中定义了两个配置文件:
·浏览器发送配置文件或推式配置文件:SAML断言在HTML表单中上传到浏览器,当用户提交表单时作为HTTP POST有效负载传递给目标站点。这种情况下,源站点从目标Web站点请求一个标志,后者返回一个授权决策标志。使用这个标志将主体重定向到目标Web站点。
·浏览器助诊文件(artifact)配置文件或者拉式配置文件:一个SAML助诊文件作为URL查询字符串的一部分带给目标站点,在返回给源站点时明确地引用一个断言。对目标站点的一些保护内容感兴趣的主体从源站点发送一个标志(SAML助诊文件),目标站点使用这个标志取得验证/授权信息并决定是否允许访问。
什么是一致性规范,为何需要它?
一致性规范有助于客观地评价SAML实现或应用程序对SAML规范的一致程度。以下原因使一致性规范很有必要:
·确保对一致性和一致性需求有共同的理解。
·促进验证和授权信息交换的互操作性。
·促进一致性测试开发中的统一性。
如果只实现了标准的子集,也能说该实现是兼容的么?
是的。对于遵循整个规范或者规范子集的SAML实现来说,可以说是兼容的。
定义一致性的粒度级别是什么?
SAML一致性根据应用程序或实现所支持的SAML绑定和配置文件来定义。对于支持的每种绑定和配置文件,必须从以下几个方面规定一致性:
·应用程序或实现是作为SAML消息的生产者、消费者还是兼具两种作用。
·应用程序或实现支持哪些断言和陈述。
基于SAML的系统的安全风险是什么?
SAML允许就验证和授权进行陈述,但是没有规定如何进行验证和建立授权。SAML陈述的消费者必须在信任SAML陈述之前确信底层的基础设施。底层的基础设施也必须包括作为客户请求和服务器响应来回传递的有效负载的安全性和机密性。
既然SAML是一种多方验证和授权系统,一个SAML事务中的合法参与者就有可能是用对其他事务有威胁的信息。
和SAML断言有关的风险:断言一旦发出就不在发出者的控制之内了。比如,消费者可能在未定的时期内持续使用断言,或者选择与最初的发出者不知道的第三方共享这些信息。
与SAML协议有关的风险:通过要求较低层次上的客户验证、客户发出的请求需要签名,或者限制SAML请求只能发给有限的已知方,可以防止拒绝服务攻击(DOS)。
与SAML协议绑定(目前只有SOAP绑定)有关的风险:
·窃听
·重放
·消息插入
·消息删除
·消息篡改
·中间人
与基于TLS/SSL的HTTP上的SOAP有关的风险:这种方法只针对单跳提供安全性、机密性和授权。对于多次中转,HTTP和TLS/SSL没有提供足够的安全性。
和SAML配置文件(浏览器/助诊文件配置文件和浏览器/POST配置文件)有关的风险:
·窃听
·偷窃用户验证信息
·偷窃持票人的标志
·重放
·消息插入
·消息删除
·消息篡改
·中间人
SAML过程
清单1示范了如何使用SAML检索关于一个主体的断言。这段代码来自Verisign所提供的SAML示例实现。
清单1. 检索属性断言
Public class SAMLAssertions {
// SAML service provider
// Change it to the SAML service provider url that you are
// trying to connect to
static final String SERVICE_URL =
"https://pilotpts.verisign.com/vspts/SamlResponder";
// Email of the subject that uniquely identifies it
static final String SUBJECT_EMAIL = "jdoe@tpms.verisign.com";
// Subject password to authenticate the user
static final String SUBJECT_PASSWORD = "password";
// The keystore to be used for getting the private key and
// the public key
static final String KEYSTORE_FILE = "saml_sample_keystore";
// Keystore password
static final String STORE_PASS = "changeit";
static final String SIGNER_ALIAS = "pilot_saml_signer";
// VeriSign attribute naming constants
static final String V_NAME_QUALIFIER = "verisign.com/ams";
static final String V_ATTR_NAMESPACE =
"verisign.com/ams/namespace/common";
static final String V_ATTR_EMAIL =
"//verisign.com/core/attr/email";
static final String V_ATTR_FIRSTNAME =
"//verisign.com/core/attr/first_name";
public static void main(String arg[]) {
NameIdentifier nameId =
new NameIdentifier(SUBJECT_EMAIL, V_NAME_QUALIFIER, "");
String[] confMethods = { Identifiers.AUTHN_METHOD_PASSWORD };
SubjectConfirmation sconf =
new SubjectConfirmation(confMethods, SUBJECT_PASSWORD);
Subject subject = new Subject(nameId, sconf);
AttributeDesignator[] reqAttrs = null;
AttributeQuery query = new AttributeQuery(subject, reqAttrs);
AttributeStatementProvider provider = null;
try {
provider = getAttributeStatementProvider();
} catch (Exception e) {
// XXX Auto-generated catch block
e.printStackTrace();
}
AttributeStatement[] statements = null;
try {
statements = provider.processAttributeQuery(query);
} catch (Exception e1) {
// XXX Auto-generated catch block
e1.printStackTrace();
}
if (statements.length == 0) {
System.out.println("No statements returned");
}
for (int i = 0; i < statements.length; i += 1) {
AttributeStatement statement = statements[i];
Authenticity authenticity = statement.getAuthenticity();
System.out.println( "Statement "+ (i + 1)+ " authenticity: "
+ authenticity.isAuthentic());
// Print attribute statement
System.out.println("--- Attribute Statement ---");
System.out.println(  "  Subject: "
+ statement.getSubject().getNameIdentifier().getValue())
// Print attribute values
Attribute[] attrs = statement.getAttributes();
for (int k = 0; k < attrs.length; k += 1) {
Attribute attr = attrs[k];
System.out.println(  "Namespace: " + attr.getAttributeNamespace());
System.out.println(" Name: " + attr.getAttributeName());
Object[] values = attr.getAttributeValues();
for (int m = 0; m < values.length; m += 1) {
System.out.println( " Value: " + values[m].toString());
}
}
}
}
private static AttributeStatementProvider
getAttributeStatementProvider() throws Exception {
// Read the keystore and get the signing cert/key.
InputStream fileInput = new FileInputStream(KEYSTORE_FILE);
KeyStore keystore =
KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(fileInput,STORE_PASS.toCharArray());
PrivateKey key =
(PrivateKey) keystore.getKey(
SIGNER_ALIAS,STORE_PASS.toCharArray());
if (key == null) {
throw new Exception(SIGNER_ALIAS +
" key not found in keystore " + KEYSTORE_FILE);
}
Certificate[] certArray =
keystore.getCertificateChain(SIGNER_ALIAS);
if (certArray == null) {
throw new Exception(SIGNER_ALIAS +
" cert not found in keystore " + KEYSTORE_FILE);
}
X509Certificate[] certs = new X509Certificate[certArray.length];
System.arraycopy(certArray, 0, certs, 0, certs.length);
// Create SOAP assertion provider factory with signing information
SOAPAssertionProviderFactory factory =
new SOAPAssertionProviderFactory(new URL(SERVICE_URL));
factory.setSigningKey(new RSASigningKey(key));
factory.setVerifyingKey(new RSAVerifyingKey(certs));
return factory.newAttributeStatementProvider(); }
}
清单1中在SOAP协议上查询主体属性的步骤描述如下:
·第1步:建立关心其属性的主体。这是通过创建SubjectIdentifier并定义SubjectConfirmation方法实现的。
·第2步:使用主体的e-mail ID作为主体的唯一标识符。
·第3步:指定验证用户所使用的方法。清单1中使用的是口令验证。
·第4步:创建AttributeDesignator对象,该对象指定了希望检索的属性。在清单1中,Verisign的SAML实现把这个数组保留为空值,检索与查询对象相关的所有属性值,这些属性在AttributeDesignator数组中指定。
·第5步:使用主体和AttributeDesignator数组创建AttributeQuery对象。
·第6步:使用密钥存储和示例SAML服务所运行的服务URL创建AttributeStatementProvider 。
·第7步:使用SOAPAssertionProviderFactory创建AttributeStatementProvider。在创建AttributeStatementProvider之前必须向SOAPAssertionProviderFactory提供签名密钥和检验密钥。签名密钥是主体的私钥,检验密钥带有附加的证书。
·第8步:对第6步创建的AttributeStatementProvider执行第5步建立的查询。获得一个AttributeStatement对象数组。该数组包含提供程序作为查询结果发送的所有属性的值。迭代陈述中的所有属性以便获得属性值。
结束语
本文考察了SAML的目标、体系结构和基本概念。SAML完成了几件事情,澄清了安全可移植性领域的一些混乱:它定义了表示需要交换的信息的标准机制,定义了交换这类信息的标准。如果您迫切需要提供安全可移植性,您就不能不考虑基于这一计划的安全可移植性产品并采用SAML作为标准。
关于作者
Manish Verma是Second Foundation的首席架构师,Second Foundation一家全球IT服务公司。Manish在软件开发生命周期的各个方面有11年的经验,曾经设计过运行在完全不同系统上的客户组织的集成策略。Manish在集成方面的专长建立在理解各种技术的基础上,包括各种不同的遗留系统、.NET、Java技术和最新的中间件技术。在进入Second Foundation之前,Manish先后在Quark Inc.、Hewlett Packard、Endura Software和The Williams Company做过软件架构师和技术主管。可以通过mverma@secf.com与Manish联系。

XML安全
 Concordia和XML安全协同工作能力
 XML安全组件:增强电子商务的安全性
 XML安全:实现安全层 第1部分
 XML安全:实现安全层 第2部分
 启用XML安全性
 探索XML加密 第1部分
 探索XML加密 第2部分
 XML签名:幕后
 XML安全:XML密钥管理规范
 澄清SAML的不实说法和误解
 XML安全:使用SAML确保可移植的信任
 
原文出处:http://www.ibm.com/developerworks/cn/xml/x-seclay4/