你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
在 Azure AD B2C 中注册 SAML 应用程序
本文介绍如何将安全断言标记语言 (SAML) 应用程序(服务提供程序)连接到 Azure Active Directory B2C (Azure AD B2C) 以进行身份验证。
开始之前,可以使用“选择策略类型”选择器来选择要设置的策略类型。 Azure Active Directory B2C 提供了两种定义用户如何与应用程序交互的方法:通过预定义的用户流,或者通过可完全配置的自定义策略。 对于每种方法,本文中所需的步骤都不同。
此功能仅适用于自定义策略。 对于设置步骤,请在前面的选择器中选择“自定义策略”。
概述
使用 Azure AD B2C 作为客户标识并访问管理解决方案的组织可能需要与使用 SAML 协议进行身份验证的应用程序集成。 下图显示了如何将 Azure AD B2C 用作标识提供者 (IdP),在基于 SAML 的应用程序中实现单一登录 (SSO)。
- 应用程序创建一个要发送到 Azure AD B2C SAML 登录终结点的 SAML AuthN 请求。
- 用户可以使用 Azure AD B2C 本地帐户或任何其他联合标识提供者(如果已配置)进行身份验证。
- 如果用户使用联合标识提供者登录,令牌响应会发送到 Azure AD B2C。
- Azure AD B2C 生成 SAML 断言并将其发送到应用程序。
观看此视频,了解如何将 SAML 应用程序与 Azure AD B2C 集成。
先决条件
对于本文中的应用场景,需具备以下项:
- 自定义策略初学者包中的 SocialAndLocalAccounts 自定义策略。 完成 Azure AD B2C 中的自定义策略中的步骤。
- 基本了解 SAML 协议,并熟悉应用程序的 SAML 实现。
- 一个已配置为 SAML 应用程序的应用程序。 它必须能够发送 SAML AuthN 请求,以及接收、解码和验证来自 Azure AD B2C 的 SAML 响应。 SAML 应用程序也称为信赖方应用程序或服务提供程序。
- SAML 应用程序的公开可用 SAML 元数据终结点或 XML 文档。
- Azure AD B2C 租户。
如果你没有 SAML 应用程序和关联的元数据终结点,可以使用我们提供的用于测试的 SAML 测试应用程序。
重要
终结点必须符合 Azure AD B2C 安全要求。 较旧的 TLS 版本和密码已弃用。 有关详细信息,请参阅 Azure AD B2C TLS 和密码套件要求。
设置证书
若要在应用程序和 Azure AD B2C 之间建立信任关系,这两个服务必须能够创建和验证彼此的签名。 在应用程序和 Azure AD B2C 中配置 X509 证书。
应用程序证书
使用情况 | 必需 | 说明 |
---|---|---|
SAML 请求签名 | 否 | 一个证书,其私钥存储在你的 Web 应用中。 应用程序使用该证书对发送到 Azure AD B2C 的 SAML 请求进行签名。 Web 应用必须通过其 SAML 元数据终结点公开公钥。 Azure AD B2C 使用应用程序元数据中的公钥来验证 SAML 请求签名。 |
SAML 断言加密 | 否 | 一个证书,其私钥存储在你的 Web 应用中。 Web 应用必须通过其 SAML 元数据终结点公开公钥。 Azure AD B2C 可以使用公钥在应用程序中加密断言。 应用程序使用私钥来解密断言。 |
Azure AD B2C 证书
使用情况 | 必需 | 说明 |
---|---|---|
SAML 响应签名 | 是 | 一个证书,其私钥存储在 Azure AD B2C 中。 Azure AD B2C 使用此证书对发送到应用程序的 SAML 响应进行签名。 应用程序读取 Azure AD B2C 中的元数据公钥以验证 SAML 响应的签名。 |
SAML 断言签名 | 是 | 一个证书,其私钥存储在 Azure AD B2C 中。 Azure AD B2C 使用此证书对 SAML 响应的 <saml:Assertion> 部分进行签名。 |
在生产环境中,我们建议使用公共证书颁发机构颁发的证书。 不过,你也可以使用自签名证书完成此过程。
创建策略密钥
若要在应用程序和 Azure AD B2C 之间建立信任关系,请创建 SAML 响应的签名证书。 Azure AD B2C 使用此证书对发送到应用程序的 SAML 响应进行签名。 应用程序读取 Azure AD B2C 的元数据公钥以验证 SAML 响应的签名。
提示
可以使用此策略密钥实现其他目的,例如对 SAML 断言进行签名。
获得证书
如果你还没有证书,则可以使用自签名证书。 自签名证书是未由证书颁发机构 (CA) 签署的安全证书,不提供由 CA 签名的证书的安全保障。
在 Windows 上,可在 PowerShell 中使用 New-SelfSignedCertificate cmdlet 来生成证书。
运行以下 PowerShell 命令来生成自签名证书。 根据应用程序和 Azure AD B2C 租户名称修改
-Subject
参数,如contosowebapp.contoso.onmicrosoft.com
。 还可调整-NotAfter
日期,为证书指定不同的过期日期。New-SelfSignedCertificate ` -KeyExportPolicy Exportable ` -Subject "CN=yourappname.yourtenant.onmicrosoft.com" ` -KeyAlgorithm RSA ` -KeyLength 2048 ` -KeyUsage DigitalSignature ` -NotAfter (Get-Date).AddMonths(12) ` -CertStoreLocation "Cert:\CurrentUser\My"
在 Windows 计算机上,搜索并选择“管理用户证书”
在“证书 - 当前用户”下,选择“个人”>“证书”>“yourappname.yourtenant.onmicrosoft.com” 。
选择该证书,然后依次选择“操作”>“所有任务”>“导出”。
选择“下一步”>“是,导出私钥”>“下一步” 。
接受“导出文件格式”的默认值,然后选择“下一步” 。
启用“密码”选项,输入证书的密码,然后选择“下一步” 。
若要指定保存证书的位置,请选择“浏览”并导航到所选的目录。
在“另存为”窗口中,输入文件名,然后选择“保存” 。
选择“下一步”>“完成”。
要让 Azure AD B2C 接受 .pfx 文件密码,必须在 Windows 证书存储导出实用工具中使用 TripleDES-SHA1 选项,而不是 AES256-SHA256 对此密码进行加密。
上传证书
需要将你的证书存储在 Azure AD B2C 租户中。
- 登录 Azure 门户。
- 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,切换到“目录 + 订阅”菜单中的 Azure AD B2C 租户。
- 选择 Azure 门户左上角的“所有服务”,然后搜索并选择“Azure AD B2C”。
- 在“概述”页上,选择“Identity Experience Framework”。
- 选择“策略密钥”,然后选择“添加” 。
- 对于“选项”,请选择“上传”。
- 对于“名称”,输入策略密钥的名称。 例如,输入“SamlIdpCert”。 前缀“B2C_1A_”会自动添加到密钥名称中。
- 浏览并选择带有私钥的证书 .pfx 文件。
- 选择“创建”。
启用策略以连接 SAML 应用程序
若要连接到 SAML 应用程序,Azure AD B2C 必须能够创建 SAML 响应。
在自定义策略初学者包中打开 SocialAndLocalAccounts\TrustFrameworkExtensions.xml。
找到 <ClaimsProviders>
一节,并添加以下 XML 代码片段来实现 SAML 响应生成器:
<ClaimsProvider>
<DisplayName>Token Issuer</DisplayName>
<TechnicalProfiles>
<!-- SAML Token Issuer technical profile -->
<TechnicalProfile Id="Saml2AssertionIssuer">
<DisplayName>Token Issuer</DisplayName>
<Protocol Name="SAML2"/>
<OutputTokenFormat>SAML2</OutputTokenFormat>
<Metadata>
<Item Key="IssuerUri">https://issuerUriMyAppExpects</Item>
</Metadata>
<CryptographicKeys>
<Key Id="SamlAssertionSigning" StorageReferenceId="B2C_1A_SamlIdpCert"/>
<Key Id="SamlMessageSigning" StorageReferenceId="B2C_1A_SamlIdpCert"/>
</CryptographicKeys>
<InputClaims/>
<OutputClaims/>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-Saml-issuer"/>
</TechnicalProfile>
<!-- Session management technical profile for SAML-based tokens -->
<TechnicalProfile Id="SM-Saml-issuer">
<DisplayName>Session Management Provider</DisplayName>
<Protocol Name="Proprietary" Handler="Web.TPEngine.SSO.SamlSSOSessionProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
配置 SAML 响应的颁发者 URI
可以在 SAML 令牌颁发者技术配置文件中更改 IssuerUri
元数据项的值。 此项更改将反映在 Azure AD B2C 做出的 SAML 响应中返回的 issuerUri
特性内。 配置应用程序以在 SAML 响应验证期间接受相同的 IssuerUri
值。
<ClaimsProvider>
<DisplayName>Token Issuer</DisplayName>
<TechnicalProfiles>
<!-- SAML Token Issuer technical profile -->
<TechnicalProfile Id="Saml2AssertionIssuer">
<DisplayName>Token Issuer</DisplayName>
<Protocol Name="SAML2"/>
<OutputTokenFormat>SAML2</OutputTokenFormat>
<Metadata>
<Item Key="IssuerUri">https://issuerUriMyAppExpects</Item>
</Metadata>
...
</TechnicalProfile>
配置策略以发出 SAML 响应
你的策略现在可以创建 SAML 响应,必须将策略配置为向应用程序发出 SAML 响应,而不是默认的 JWT 响应。
创建为 SAML 配置的注册或登录策略
在初学者包的工作目录中创建 SignUpOrSignin.xml 文件的副本,并使用新名称保存该副本。 本文以“SignUpOrSigninSAML.xml”为例。 此文件是你对信赖方的策略文件。 它默认配置为发出 JWT 响应。
在首选编辑器中打开“SignUpOrSigninSAML.xml”文件。
更改以下项的值:
PolicyId
至B2C_1A_signup_signin_saml
PublicPolicyUri
重命名为http://<tenant-name>.onmicrosoft.com/B2C_1A_signup_signin_saml
。 将<tenant-name>
占位符替换为 Azure AD B2C 租户域名的子域。 例如,如果租户主域为contoso.onmicrosoft.com
,请使用contoso
。 如果没有租户名称,请了解如何读取租户详细信息。
<TrustFrameworkPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06" PolicySchemaVersion="0.3.0.0" TenantId="<tenant-name>.onmicrosoft.com" PolicyId="B2C_1A_signup_signin_saml" PublicPolicyUri="http://<tenant-name>.onmicrosoft.com/B2C_1A_signup_signin_saml">
用户旅程结束时,Azure AD B2C 将包含
SendClaims
步骤。 此步骤引用令牌颁发者技术配置文件。 若要发出 SAML 响应而不是默认的 JWT 响应,请修改SendClaims
步骤,以引用新的 SAML 令牌颁发者技术配置文件Saml2AssertionIssuer
。
紧靠在 <RelyingParty>
元素的前面添加以下 XML 代码片段。 此 XML 将覆盖 SignUpOrSignIn 用户旅程中的业务流程步骤 7。
如果已从初学者包中的不同文件夹启动,或者通过添加或删除业务流程步骤自定义了用户旅程,请确保 order
元素中的编号对应于用户旅程中为令牌颁发者步骤指定的编号。 例如,在其他初学者包文件夹中,LocalAccounts
、SocialAccounts
和 SocialAndLocalAccountsWithMfa
的对应步骤编号分别为 4、6、9。
<UserJourneys>
<UserJourney Id="SignUpOrSignIn">
<OrchestrationSteps>
<OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer"/>
</OrchestrationSteps>
</UserJourney>
</UserJourneys>
信赖方元素确定应用程序使用的协议。 默认为 OpenId
。 必须将 Protocol
元素更改为 SAML
。 输出声明将创建到 SAML 断言的声明映射。
将 <RelyingParty>
元素中的整个 <TechnicalProfile>
元素替换为以下技术配置文件 XML。
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="SAML2"/>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="email" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="objectId"/>
</OutputClaims>
<SubjectNamingInfo ClaimType="objectId" ExcludeAsClaim="true"/>
</TechnicalProfile>
信赖方的最终策略文件应如以下 XML 代码所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
PolicySchemaVersion="0.3.0.0"
TenantId="contoso.onmicrosoft.com"
PolicyId="B2C_1A_signup_signin_saml"
PublicPolicyUri="http://contoso.onmicrosoft.com/B2C_1A_signup_signin_saml">
<BasePolicy>
<TenantId>contoso.onmicrosoft.com</TenantId>
<PolicyId>B2C_1A_TrustFrameworkExtensions</PolicyId>
</BasePolicy>
<UserJourneys>
<UserJourney Id="SignUpOrSignIn">
<OrchestrationSteps>
<OrchestrationStep Order="7" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="Saml2AssertionIssuer"/>
</OrchestrationSteps>
</UserJourney>
</UserJourneys>
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUpOrSignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="SAML2"/>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="email" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="objectId"/>
</OutputClaims>
<SubjectNamingInfo ClaimType="objectId" ExcludeAsClaim="true"/>
</TechnicalProfile>
</RelyingParty>
</TrustFrameworkPolicy>
注意
可以遵循上述相同过程来实现其他类型的用户流(例如登录、密码重置或配置文件编辑流)。
上传策略
保存更改,并将新的 TrustFrameworkExtensions.xml 和 SignUpOrSigninSAML.xml 策略文件上传到 Azure 门户 。
测试 Azure AD B2C IdP SAML 元数据
上传策略文件后,Azure AD B2C 将使用配置信息来生成应用程序使用的标识提供者 SAML 元数据文档。 SAML 元数据文档包含服务的位置,例如登录方法、注销方法和证书。
以下 URL 提供了 Azure AD B2C 策略元数据:
https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/<policy-name>/samlp/metadata
将 <tenant-name>
替换为 Azure AD B2C 租户的名称。 将 <policy-name>
替换为策略的名称 (ID)。 下面是一个示例:
https://contoso.b2clogin.com/contoso.onmicrosoft.com/B2C_1A_signup_signin_saml/samlp/metadata
在 Azure AD B2C 中注册 SAML 应用程序
要使 Azure AD B2C 信任你的应用程序,你需要创建一个 Azure AD B2C 应用程序注册。 注册包含配置信息,如应用程序的元数据终结点。
- 登录 Azure 门户。
- 如果有权访问多个租户,请选择顶部菜单中的“设置”图标,切换到“目录 + 订阅”菜单中的 Azure AD B2C 租户。
- 在左侧菜单中,选择“Azure AD B2C”。 或者,选择“所有服务”,然后搜索并选择“Azure AD B2C”。
- 选择“应用注册”,然后选择“新建注册” 。
- 输入应用程序的“名称”。 例如,输入“SAMLApp1”。
- 在“支持的帐户类型”下,选择“仅此组织目录中的帐户” 。
- 在“重定向 URI”下,选择“Web”,然后输入
https://localhost
。 稍后你将在应用程序注册的清单中修改此值。 - 选择“注册” 。
在 Azure AD B2C 中配置应用程序
对于 SAML 应用,需要在应用程序注册的清单中配置几个属性。
- 在 Azure 门户中,转到在上一节中创建的应用程序注册。
- 在“管理”下,选择“清单”以打开清单编辑器。 然后修改以下各节中介绍的属性。
添加标识符
当 SAML 应用程序向 Azure AD B2C 发出请求时,SAML AuthN 请求将包含一个 Issuer
特性。 此特性的值通常与应用程序的元数据 entityID
值相同。 Azure AD B2C 使用此值在目录中查找应用程序注册并读取配置。 要使此查找操作成功,必须使用与 Issuer
特性匹配的值来填充应用程序注册中的 identifierUri
。
在注册清单中,找到 identifierURIs
参数并添加适当的值。 此值将与在应用程序的 SAML AuthN 请求中为 EntityId
配置的值,以及应用程序元数据中的 entityID
值相同。 还将需要找到 accessTokenAcceptedVersion
参数,并将值设置为 2
。
重要
如果不将 accessTokenAcceptedVersion
更新为 2
,你将收到一条错误消息,要求提供一个经过验证的域。
以下示例展示了 SAML 元数据中的 entityID
值:
<EntityDescriptor ID="id123456789" entityID="https://samltestapp2.azurewebsites.net" validUntil="2099-12-31T23:59:59Z" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
identifierUris
属性仅接受域 tenant-name.onmicrosoft.com
上的 URL。
"identifierUris":"https://tenant-name.onmicrosoft.com/app-name",
与 Azure AD B2C 共享应用程序的元数据
在应用程序注册由其 identifierUri
值加载后,Azure AD B2C 将使用应用程序的元数据来验证 SAML AuthN 请求,并确定如何做出响应。
我们建议让应用程序公开一个可公开访问的元数据终结点。
如果在 SAML 元数据 URL 和应用程序注册的清单中都指定了一些属性,则这些属性将合并。 会优先处理元数据 URL 中指定的属性,其优先级更高。
以 SAML 测试应用程序为例,可以在应用程序清单中为 samlMetadataUrl
使用以下值:
"samlMetadataUrl":"https://samltestapp2.azurewebsites.net/Metadata",
替代或设置断言使用者 URL(可选)
可以配置 Azure AD B2C 要向其发送 SAML 响应的回复 URL。 可以在应用程序清单中配置回复 URL。 当应用程序未公开一个可公开访问的元数据终结点时,此配置非常有用。
SAML 应用程序的回复 URL 是应用程序预期在其上接收 SAML 响应的终结点。 应用程序通常在元数据文档中提供此 URL 作为 AssertionConsumerService
元素的 Location
特性,如以下示例中所示:
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
...
<AssertionConsumerService index="0" isDefault="true" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://samltestapp2.azurewebsites.net/SP/AssertionConsumer" />
</SPSSODescriptor>
如果缺少应用程序的元数据 AssertionConsumerService
元素,或者你想要重写它,请配置应用程序注册清单 replyUrlsWithType
属性。 Azure AD B2C 使用 replyUrlsWithType
在用户使用 HTTP-POST
绑定类型登录后重定向用户。
以 SAML 测试应用程序为例,可将 replyUrlsWithType
的 url
属性设置为以下 JSON 代码片段中显示的值:
"replyUrlsWithType":[
{
"url":"https://samltestapp2.azurewebsites.net/SP/AssertionConsumer",
"type":"Web"
}
],
替代或设置注销 URL(可选)
注销 URL 定义了注销请求后将用户重定向到的位置。 应用程序通常在元数据文档中提供此 URL 作为 SingleLogoutService
元素的 Location
特性,如下面的示例中所示:
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://samltestapp2.azurewebsites.net/logout" ResponseLocation="https://samltestapp2.azurewebsites.net/logout" />
</SPSSODescriptor>
如果缺少应用程序的元数据 SingleLogoutService
元素,请配置应用程序注册清单 logoutUrl
属性。 Azure AD B2C 使用 logoutURL
在用户使用 HTTP-Redirect
绑定类型注销后重定向用户。
以 SAML 测试应用程序为例,你会将 logoutUrl
属性设置为 https://samltestapp2.azurewebsites.net/logout
:
"logoutUrl": "https://samltestapp2.azurewebsites.net/logout",
注意
如果你选择在应用程序清单中配置回复 URL 和注销 URL,而不通过 samlMetadataUrl
属性填充应用程序的元数据终结点,Azure AD B2C 将不会验证 SAML 请求签名。 也不会加密 SAML 响应。
在 SAML 应用程序中将 Azure AD B2C 配置为 SAML IdP
最后一步是在 SAML 应用程序中将 Azure AD B2C 启用为 SAML IdP。 应用程序各不相同,因此步骤也不相同。 有关详细信息,请参阅应用的文档。
可以在应用程序中将元数据配置为静态元数据或动态元数据 。 在静态模式下,复制 Azure AD B2C 策略元数据中的所有或一部分元数据。 在动态模式下,提供元数据的 URL 并允许应用程序动态读取元数据。
通常需要以下部分或全部内容:
元数据:使用格式 。
颁发者:SAML 请求的
issuer
值必须与在应用注册清单的identifierUris
元素中配置的 URI 之一匹配。 如果 SAML 请求的issuer
名称不存在于identifierUris
元素中,则issuer
。 例如:https://contoso.onmicrosoft.com/app-name
。登录 URL、SAML 终结点、SAML URL:检查 Azure AD B2C SAML 策略元数据文件中 XML 元素的值。
证书:此证书为 B2C_1A_SamlIdpCert,但不包含私钥。 若要获取证书的公钥:
- 转到之前指定的元数据 URL。
- 复制
<X509Certificate>
元素中的值。 - 将其粘贴到文本文件中。
- 将该文本文件另存为 .cer 文件。
使用 SAML 测试应用进行测试
可以使用我们的 SAML 测试应用程序来测试你的配置:
- 更新租户名称。
- 更新策略名称。 例如,使用 B2C_1A_signup_signin_saml。
- 指定颁发者 URI。 使用在应用程序注册清单的
identifierUris
元素中找到的 URI 之一。 例如,使用https://contoso.onmicrosoft.com/app-name
。
选择“登录”,应会显示用户登录屏幕。 登录后,SAML 响应将发回示例应用程序。
受支持的和不支持的 SAML 形式
可通过你自己的元数据终结点支持以下 SAML 应用程序方案:
- 指定应用程序或服务主体对象中的多个注销 URL 或注销 URL 的 POST 绑定。
- 指定签名密钥,以验证应用程序或服务主体对象中的信赖方请求。
- 在应用程序或服务主体对象中指定令牌加密密钥。
- 指定 IdP 发起的登录,其中的标识提供者是 Azure AD B2C。
后续步骤
- 从 Azure AD B2C GitHub 社区存储库获取 SAML 测试 Web 应用。
- 请参阅用于在 Azure AD B2C 中注册 SAML 应用程序的选项。
- 了解如何通过开发人员最佳做法构建复原能力。