假设您已阅读本系列中的第 1 篇文章,本教程(第 2 部分)不会重复累述 Salesforce 联合单点登录 (SSO) 的基础知识。本教程主要将介绍如何使用 IBM® WebSphere DataPower(下文简称 DataPower)实现身份提供程序向 Salesforce 发起的 SSO(受一个已加密和签名的 SAML 断言支持)。图 1 和图 2 给出了此解决方案的总体概括图。
图 1. 身份提供程序向 Salesforce 发起的 SSO 登录的概括图
图 2. 身份提供程序发起的 SSO 登录流程
回页首
这一节将提供在 Force.com 平台中实现 SSO 设置的步骤。如果您已经实现了本系列任何教程演示的示例,则无需重复同样的步骤。但是,请确保您已配置本示例需要的额外步骤。
回页首
图 3. 创建 Salesforce 用户帐户(开发人员版)
点击查看大图
关闭 [x]
用户 ID: sdfc.user@sdfc.com
联合 ID: sdfc.user@sso.sdfc.com
图 4. 输入一个联合 ID 来启用 SSO
图 5. Salesforce 上的用户帐户(标准平台用户)详细信息
点击查看大图
关闭 [x]
回页首
证书用于向外部身份提供程序执行经过验证的 SSO。您需要使用这个 Salesforce 证书在身份提供程序一端加密 SAML 断言。创建证书后,下载它并将它保存到您的本地系统中。本教程系列演示的示例使用下面这个自签名证书(标签: Salesforce SSO ),如图 6 和图 7 所示。
图 6. Salesforce 上的证书列表
点击查看大图
关闭 [x]
图 7. 自签名证书(标签:Salesforce SSO)详细信息页面
点击查看大图
关闭 [x]
回页首
使用 “My Domain”,您可定义一个自定义的 Salesforce 域名。这个域名可帮助您以多种方式更好地管理您组织的登录和身份验证。请参阅 Salesforce 文档 了解域管理详细信息。本教程系列演示的示例使用了以下域名。建议对您的组织使用一个合适的域名。一个域名示例: https://dipak-sdfc-dev-ed.my.salesforce.com/ 。
图 8. Salesforce 上的 My Domain 概述页面
点击查看大图
关闭 [x]
回页首
https://dipak-sdfc-dev-ed.my.salesforce.com?so=00DF0000000ghLC&sc=0LEF0000000Kytb 。 图 9. Salesforce 上的 SAML SSO 设置
点击查看大图
关闭 [x]
图 10. Salesforce 上的 SAML SSO 设置详细信息
点击查看大图
关闭 [x]
回页首
这一节将介绍如何开发必要的 DataPower 工件,主要包括 HTTPS 前端处理函数、一个包含所需的处理策略规则的多协议网关,以及一个 AAA 策略。
回页首
temporary:// 目录下载它。如果已实现本教程系列第 1 部分 中演示的示例,可以重用同样的加密配置。确保您配置了一个加密证书并导入了第 2 步中下载的 Salesforce 证书,因为需要使用它来加密 SAML 断言。 图 11. 本示例中使用的 DataPower 加密密钥
图 12. 本示例中使用的 DataPower 加密证书
图 13. 配置加密证书并导入 Salesforce 证书
图 14. 使用 DataPower 加密密钥配置加密身份凭据
图 15. 配置加密验证凭据
图 16. 配置加密配置文件
图 17. 配置 SSL 代理配置文件
回页首
创建一个 HTTPS 前端处理函数(图 18)来接受来自浏览器的 SSO 请求。
图 18. 配置 HTTPS 前端处理函数
点击查看大图
关闭 [x]
回页首
使用动态后端路由创建一个多协议网关(图 19)。确保为请求和响应数据类型都选择了 Non-XML ,以便处理 HTTP 格式数据和 HTML 数据。下一步(第 8 步)介绍多协议网关策略的详细信息。
图 19. 配置多协议网关
点击查看大图
关闭 [x]
回页首
方向:客户端到服务器。
/favicon.ico var://service/mpgw/skip-backside 图 20. 处理来自浏览器的 favicon.ico 请求的多协议网关策略规则
点击查看大图
关闭 [x]
图 21. 处理来自浏览器的 SSO 登录请求的多协议网关策略规则
点击查看大图
关闭 [x]
方向:客户端到服务器。
/sso/salesforce/login 备注: 依据您组织的标准而使用合适的 URL。 按照第 9 步中的描述创建一个 AAA 策略。
使用教程的下载部分中提供的 XSLT ( remove-specific-attribute.xsl ) (如清单 1 所示),从 <SubjectConfirmationData> 元素中删除 @NotBefore 属性,因为 Salesforce SAML Assertion Validator Framework 不支持此属性。
图 22. 在转换操作中使用 XSLT 从 SAML 断言 XML 中删除属性
点击查看大图
关闭 [x]
清单 1. 从 SAML 断言 XML 中删除一个特定属性的 XSLT [remove-specific-attribute.xsl]
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" extension-element-prefixes="dp" exclude-result-prefixes="dp" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/> <xsl:strip-space elements="*"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <xsl:template match="/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:protocol' and local-name()='Response']/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:assertion' and local-name()='Assertion']/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:assertion' and local-name()='Subject']/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:assertion' and local-name()='SubjectConfirmation']/*[namespace-uri() ='urn:oasis:names:tc:SAML:2.0:assertion' and local-name() ='SubjectConfirmationData']/@NotBefore"/> </xsl:stylesheet>
加密
此操作使用 Salesforce 证书加密 SAML 断言。指定以下 XPATH(清单 2)来创建一个文档加密映射,如图 23 和图 24 所示。
清单 2. 文档加密映射中使用的 XPATH
/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:protocol' and local-name()='Response']/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:assertion' and local-name()='Assertion']
图 23. 加密 SAML 断言
点击查看大图
关闭 [x]
图 24. 用于加密的文档加密映射
点击查看大图
关闭 [x]
签名
此操作对加密的 SAML 断言 XML 进行签名(图 25)。使用清单 3 中的 XPATH。
清单 3. SAML 断言 XML 中的 XPATH 需要签名
/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:protocol' and local-name()='Response']
图 25. 对 SAM 断言 XML 执行签名
点击查看大图
关闭 [x]
成功执行身份验证后,这个 转换 操作生成一个 HTML 页面,其中包含一个包含 HTTP POST 操作的 HTML FORM,包含一个 base-64 编码的 SAML 断言 XML 作为隐藏的参数。图 36 显示了在成功验证后 DataPower 响应的一个示例 HTML 页面。使用清单 4 中所示的 XSLT ( SSO-Generate-HTML-Idp.xsl ),本教程的下载部分中也有提供。确保使用第 4 步中获取的合适的 Salesforce 登录 URL 更新了该 XSLT(XSLT 变量: sdfcLoginURL ) 。
图 26. 生成 HTML 响应的 XSLT 转换
点击查看大图
关闭 [x]
清单 4. 生成 HTML 页面的 XSLT [SSO-Generate-HTML-Idp.xsl]
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" extension-element-prefixes="dp" exclude-result-prefixes="dp" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions"> <xsl:output method="html" omit-xml-declaration="yes"/> <xsl:template match="/"> <xsl:param name="sdfcLoginURL" select="'https://dipak-sdfc-dev-ed.my.salesforce.com?so=00DF0000000ghLC &sc=0LEF0000000Kytb'"/> <xsl:variable name="signedSamlSerialized"> <dp:serialize select="/" omit-xml-decl="yes"/> </xsl:variable> <xsl:variable name="base64Samldata" select="dp:encode($signedSamlSerialized,'base-64')"/> <html> <head> <title>Login to Salesforce</title> <meta http-equiv="Cache-Control" content="no-cache"/> <meta http-equiv="Pragma" content="no-cache"/> <meta http-equiv="Expires" content="-1"/> <meta http-equiv="X-UA-Compatible" content="IE=8"/> <style type="text/css"> .body{background-color: #3EB1D0;} .data{ background-color: #C6EDEC; margin-top: 10%; margin-left: 20%; margin-right: 20%; font-family: verdana; color: #0A6DA8; } .headline{font-size: 50px;} .button{ background-color: #F5DAA3; color: #0D75AA; font-size: x-large; } </style> </head> <body class="body"> <div align="center" class="data"> <div> <form method="POST" enctype="application/x-www-form-urlencoded"> <xsl:attribute name="action"> <xsl:value-of select="$sdfcLoginURL"/> </xsl:attribute> <div class="headline"> <i><b>Salesforce Login</b></i> </div> <div><h2>Welcome<span><i><b> <xsl:value-of select="dp:variable('var://context/WSM/identity/username')"/></b></i> </span></h2></div> <div> <h4> <p>Clicking Submit button will redirect you to Salesforce home page</p> <p>Please contact <a href="mailto:support@example.com">support@example.com</a> if you experience any issues during Salesforce Login</p></h4> </div> <div> <input type="hidden" name="idpConfig.recipient"> <xsl:attribute name="value"> <xsl:value-of select="$sdfcLoginURL"/> </xsl:attribute> </input> <input type="hidden" name="SAMLResponse"> <xsl:attribute name="value"> <xsl:value-of select="$base64Samldata"/> </xsl:attribute> </input> <input type="hidden" name="RelayState"> <xsl:attribute name="value"> <xsl:value-of select="''"/> </xsl:attribute> </input> </div> <br/> <div> <input class="button" type="submit" name="submit" value="Login to Salesforce"/> </div> <br/> </form> </div> </div> </body> </html> </xsl:template></xsl:stylesheet> var://service/mpgw/skip-backside 图 27. 跳过后端路由的高级操作
图 28. 结果操作
回页首
图 29. AAA 操作
图 30. AAA 策略 – 从请求中提取身份
图 31. AAA 策略 – 验证用户
图 32. AAA 策略 – 授权请求
图 33. AAA 策略 – 生成 SAML 断言响应
点击查看大图
关闭 [x]
图 34. AAA 策略 – SAML 属性
点击查看大图
关闭 [x]
清单 5. 示例 AAA 策略信息文件
<?xml version="1.0" encoding="utf-8"?> <AAAInfo xmlns="http://www.datapower.com/AAAInfo"> <FormatVersion>1</FormatVersion> <Filename>local:///AAAInfoPolicy.xml</Filename> <Summary>AAA Policy Info XML file</Summary> <Authenticate> <Username>dipakpal</Username> <Password>dipakpal-password</Password> <OutputCredential>dipakpal@sso.sdfc.com</OutputCredential> </Authenticate> <Authenticate> <Username>sdfc.user</Username> <Password>sdfc-password</Password> <OutputCredential>sdfc.user@sso.sdfc.com</OutputCredential> </Authenticate> <Authenticate> <CustomToken>https://dipak-sdfc-dev-ed.my.salesforce.com</CustomToken> <OutputCredential>saml.auth.request.issuer</OutputCredential> </Authenticate> <Authenticate> <DN>CN=Alice, O=DataPower, L=Cambridge, ST=MA, C=US</DN> <OutputCredential>admin</OutputCredential> </Authenticate> <Authenticate> <IPHost>127.0.0.1</IPHost> <OutputCredential>admin</OutputCredential> </Authenticate> <Authenticate> <IPHost>::1</IPHost> <OutputCredential>admin</OutputCredential> </Authenticate> <Authenticate> <Username>guest</Username> <Password>guest</Password> <OutputCredential>user</OutputCredential> </Authenticate> <Authorize> <InputCredential>dipakpal@saml.sdfc.com</InputCredential> <InputResource>/sso/*</InputResource> <Access>allow</Access> </Authorize> <Authorize> <InputCredential>sdfc.user@sso.sdfc.com</InputCredential> <InputResource>/sso/*</InputResource> <Access>allow</Access> </Authorize> <Authorize> <InputCredential>saml.auth.request.issuer</InputCredential> <InputResource>/sso/*</InputResource> <Access>allow</Access> </Authorize> <Authorize> <InputCredential>guest</InputCredential> <InputResource>/sso/salesforce</InputResource> <Access>deny</Access> </Authorize> <Authorize> <InputCredential>admin</InputCredential> <InputResource>/sso/salesforce</InputResource> <Access>allow</Access> </Authorize> <Authorize> <InputCredential> <Version>3</Version> <SerialNumber>0</SerialNumber> <SignatureAlgorithm>sha1WithRSAEncryption</SignatureAlgorithm> <Issuer>C=US, ST=MA, L=Cambridge, O=DataPower, CN=Alice</Issuer> <NotBefore>2002-11-23T01:15:33Z</NotBefore> <NotAfter>2012-11-23T01:15:33Z</NotAfter> <Subject>C=US, ST=MA, L=Cambridge, O=DataPower, CN=Alice</Subject> <SubjectPublicKeyAlgorithm>rsaEncryption</SubjectPublicKeyAlgorithm> <Extensions/> </InputCredential> <InputResource>/sso/*</InputResource> <Access>allow</Access> </Authorize> </AAAInfo>
回页首
在 Web 浏览器中输入您的身份提供程序(DataPower)SSO 登录 URL(比如 https://<dp-host:port>/sso/salesforce/login ),如图 35 所示。在成功执行身份验证后, DataPower 将使用一个 SSO 重定向(HTTP POST 绑定)页面作为响应,如图 36 所示,其中包含一个具有 HTTP POST 操作的 HTML FORM,还包含一个 base-64 编码的 SAML 断言 XML 作为隐藏参数。它需要用户单击 Login to Salesforce 按钮来提交 HTML 页面,这会导致将一个 HTTP POST 请求提交到 Salesforce 登录 URL(比如 https://dipak-sdfc-dev-ed.my.salesforce.com?so=00DF0000000ghLC&sc=0LEF0000000Kytb )。
图 35. 用户通过 Web 浏览器进行的 SSO 登录尝试
点击查看大图
关闭 [x]
图 36. 成功身份验证后的 SSO 重定向(HTTP POST 绑定)页面
点击查看大图
关闭 [x]
一个 SAML 断言包含来自身份提供程序的一个联合 ID(例如 sdfc.user@sso.sdfc.com )。Salesforce 使用 SAML 断言中嵌入的签名,针对 DataPower 证书来验证消息完整性,该证书已在 SSO 设置过程中上传。在成功验证签名后,它将解密加密的断言并处理 SAML 断言陈述,提取并验证联合 ID,并在成功验证后重定向到着陆页。图 37 显示了尝试 SSO 登录成功后的一个示例 Salesforce 着陆页。
图 37. 成功 SSO 登录后的 Sales 着陆页
点击查看大图
关闭 [x]
回页首
我们假设您熟悉常用的 DataPower 调试和故障排除技术,因此本教程主要关注 Salesforce。
您可以使用 Google Chrome 中的 开发人员工具 捕获 base64 加密的 SAML 断言数据,如图 38 和图 39 所示。尽管可以从 HTML 页面源代码获取此数据,但使用 Google Chrome 中的 开发人员工具 或 Internet Explorer 可帮助您分析 HTTP 事件,包括请求/响应标头和数据结构。您可以使用任何在线工具(比如 http://www.string-functions.com/base64decode.aspx )解码 (base-64) 此数据,获取 SAML 断言 XML。清单 6 给出了本示例生成的一个已加密和签名的示例 SAML 断言 XML。
图 38. 启动 Google Chrome 中的开发人员工具
图 39. 从 HTML 捕获 base-64 编码的 SAML 断言 XML
点击查看大图
关闭 [x]
清单 6. 示例 SAML 断言 XML(已加密和签名)
<samlp2:Response Version="2.0" ID="SAML-12b7a404-a031-4ecf-a163-5aaaa553774b" IssueInstant="2014-07-27T23:45:17Z" Destination="https://dipak-sdfc-dev-ed.my.salesforce.com?so=00DF0000000ghLC" xmlns:samlp2="urn:oasis:names:tc:SAML:2.0:protocol"> <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"> https://datapowersso.ibm.com/</saml2:Issuer> <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <Reference URI="#SAML-12b7a404-a031-4ecf-a163-5aaaa553774b"> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <Transform Algorithm=">http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>yC4KceSHBpKIEUicoDd53aflPME=</DigestValue> </Reference> </SignedInfo> <SignatureValue>jG2bMMDWAwE8hiolqtqRihlZvR0dy/HgVgYE5fFge3nRmDNShw5EaSETLYpLiRJQeV Xwbkdb1uO+NiUDvakT1LOx9M2VRVv............................</SignatureValue> <KeyInfo> <X509Data> <X509Certificate>MIIDtzCCAp+gAwIBAgIIAhBEWantyAswDQYJKoZIhvcNAQEFBQAwQjELMAk GA1UEBhMCVVMxDDAKBgNVBAoTA0lCTTEMMA.............................</X509Certificate> <X509IssuerSerial> <X509IssuerName>CN=DATAPOWER-SDFC, OU=GBS, O=IBM, C=US</X509IssuerName> <X509SerialNumber>148693939596937227</X509SerialNumber> </X509IssuerSerial> </X509Data> </KeyInfo> </Signature> <samlp2:Status> <samlp2:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp2:Status> <saml2:EncryptedAssertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"> <xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc/> <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <xenc:EncryptedKey Recipient="name:Salesforce-SSO-Cert"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <dsig:KeyInfo> <dsig:KeyName>Salesforce-SSO-Cert</dsig:KeyName> </dsig:KeyInfo> <xenc:CipherData> <xenc:CipherValue>ZkliWyMXhrCR+67rKLeEsF5YJqm0q0vDch3RfYgAaMQgW4tXWUZT DjXzZusu3b6d7jGWb7R2MJV9WDszbhQqNz4uIWN............................</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedKey> </dsig:KeyInfo> <xenc:CipherData> <xenc:CipherValue>dpzato9nnC3SGhdckfu6eG3PdN+PwcUNWdmiNVduGhktoeVbSeIVUICw9H N5KSm8YsCdsSLf+HhVa6dRBdR5NgJKV26ZFh57V58jc0RT34lVNOLKF2JqT72KUdxWpBt0NSzEq4bZA3tu/ho+4o VOCK/IFGk0zjJ/FHa2gA9v1ocWpU7UOpGsZsr9............................</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </saml2:EncryptedAssertion> </samlp2:Response>
以管理员身份登录到 Salesforce 并验证 base-64 编码的 SAML 断言,检查 SSO 身份提供程序 (DataPower) 是否生成了 Salesforce 所期望的正确的 SAML 断言。图 40 到图 43 显示了使用 Force.com 的 SAML Assertion Validator Framework 执行 SAML 断言验证的过程。
图 40. 启动 Salesforce 中的 SAML Assertion Validator Framework
点击查看大图
关闭 [x]
图 41. 将 base-64 编码的 SAML 断言输入到 Salesforce SAML Validator 中
图 42. 在 Salesforce SAML Validator 上成功验证 SAML 断言
点击查看大图
关闭 [x]
图 43.包含过期的时间戳的无效 SAML 断言
点击查看大图
关闭 [x]
测试 SSO 登录期间,您可以检查一个 Salesforce 管理员登录名在 Force.com 上的登录历史。图 44 显示了 Force.com 站点上的登录历史页面,这可以帮助您排除 SSO 登录故障。
图 44. Force.com 上的登录历史页面
点击查看大图
关闭 [x]
回页首
拥有较少 Salesforce 用户的组织可能不需要这个单点登录解决方案,因为他们可继续使用标准 Salesforce 登录流程。但是,拥有大量 Salesforce 用户的组织可利用此解决方案,为其所有内部应用程序以及基于云的和外部应用程序(Force.com)实现一个基于 DataPower 的 SSO 基础架构,这支持使用外部 SSO 身份提供程序执行联合身份管理。
要继续学习本系列,请参阅以下教程: