作为一种在各个服务之间交换认证和授权信息的方法,安全断言标记语言(SecurityAssertionMarkupLanguage,SAML)2.0经常被企业用在构建内部单点登录(singlesign-on,SSO)方案的过程中,以实现用户登录到统一的身份认证服务处,进而授予他们对于其他内部服务子集的访问权限。
从安全角度来看,采用SAML/SSO的优势主要体现在如下方面:
提供单一的身份来源。当有员工加入或离开公司时,您既不必事无巨细地去更新每一项内部服务,又不必担心错过某个关联性的重要服务。
强制执行一致性的认证。可实施SAML/SSO的方法包括:多因素认证和会话持续时间等。
下面,我们将重点讨论SSO和SAML2.0的认证机制与重要性。
SAML的相关术语
主体(Principal)
主体是参与认证的用户。您可以将其视为屏幕后面的实际访问者。在下文中,我们将其假设为JohnSmith。主体通常会带有诸如:名字、姓氏、电子邮件地址等附加的元数据(metadata)。此类元数据往往也被称为身份信息(identityinformation),下面我们将重点阐述其重要性。
身份提供者(IdentityProvider)
身份提供者常被简称IdP,是提供身份信息和认证判断的源服务。我们可以将身份提供者视为包含身份信息的数据库。它能够认证主体,并将身份信息返回给服务提供者(详见下文)。其中,最常见身份提供者应用包括:Auth0、活动目录联合服务(ActiveDirectoryFederationServices,ADFS)和Okta。在实践中,人们往往会将组织的所有用户身份都整合到一个身份提供者处。
服务供应者(ServiceProviders)
服务提供者通常被缩写为SP,是向主体要求进行认证和获取身份信息的服务。服务提供者获取由身份提供者提供的认证响应,并使用该信息来创建和配置各种会话。也就是说,服务提供者是某个应用程序,它通过为其用户提供单点登录(SSO)机制,来实现资源的登录和访问。
此类应用程序除了知晓主体的名称或邮件地址以外,还需要请求获得主体的其他身份信息,以实现基于角色的访问控制(role-basedaccesscontrol,RBAC)。典型的服务提供者应用包括:Github、GoogleApps、以及Teleport(针对SSH和Kubernetes的一种访问解决方案)。
流程(Flows)
目前,SAML支持两种不同类型的流程:由服务提供者初始化的流程、以及由身份提供者初始化的流程。服务提供者初始化的流程往往是从服务提供者开始,被重定向到身份提供者处进行认证,然后再被重定向回服务提供者。该流程通常在用户单击“使用SSO登录”按钮时被启动。
绑定(Bindings)
绑定是指在服务提供者和身份提供者之间传输的数据格式。HTTP重定向绑定和HTTPPOST绑定是目前最为流行的两种模式。其中,HTTP重定向绑定使用HTTP重定向和查询参数来传输数据;此类绑定通常被用在认证的请求中。HTTPPOST绑定则使用各种HTTPPOST表单来传输数据,此类绑定通常被用在认证的响应中。
断言(Assertions)
断言是身份提供者对主体所做的声明,包括:主体的电子邮件地址、与之关联的组或角色等。服务提供者使用断言为主体创建和配置会话。也就是说,断言定义了身份提供者在向服务提供者传送的过程中,包含了主体具有哪些身份信息。
SAML的登录流
为了说明SAML登录的工作原理,我们将在如下示例中使用Teleport作为服务提供者,使用Auth0作为身份提供者。SAML登录的基本流程,如下图所示:
1.用户单击“通过Auth0登录”按钮,选择使用SAML登录,而不是使用Teleport的内置用户数据库。Teleport会将用户重定向到Auth0处。在此,用户便是SAML中的主体。
2.Auth0要求用户提供他们的用户名(或电子邮件)、密码、以及认证令牌作为第二认证因素(2FA)。
3.如果提供的信息正确,Auth0将获取主体的身份信息,并将其作为断言返回给Teleport。
4.Teleport会从Auth0处接收到身份信息,进而创建用户会话。
配置
身份提供者往往拥有自己独特的配置方法。下面是身份提供者与服务提供者在协作时需要的最少配置集:
断言消费者服务(AssertionConsumerService,ACS)的URL是服务提供者的端点,身份提供者将其认证的响应重定向到该端点处。由于它将被用于传输个人身份信息(PersonallyIdentifiableInformation,PII),因此该端点应当被配置为HTTPS类型。
生成并上传用于签发认证请求的签名密钥(详见下文)。
对断言中所包含的有关主体信息的来源和格式进行配置。身份提供者至少需要发送NameID、以及组成员等信息。
服务提供者的配置通常比较简单,并且可以通过解析身份提供者所提供的元数据,来自动完成配置。如下Django(译者注:一个开放源代码的Web应用框架,由Python编写而成。)代码段展示了简单的身份提供者元数据的XML。其中,最重要的标签当属SingleSignOnService和KeyDescriptor。具体而言,SingleSignOnService标签定义了有待发送认证请求的绑定和端点,而KeyDescriptor标签则包含了有待认证响应的身份提供者的公钥。
md:EntityDescriptormd:IDPSSODescriptormd:KeyDescriptoruse="signing"ds:KeyInfods:XDatads:XCertificateMIICMjCCAZugAwIBAgIBADANBgkqhkiG9w0BAQ0FADA2MQswCQYDVQQGEwJ1czELMAkGA1UECAwCQ0ExDDAKBgNVBAoMA2lkcDEMMAoGA1UEAwwDaWRwMB4XDTE5MDQyNjE4NTIxOFoXDTIwMDQyNTE4NTIxOFowNjELMAkGA1UEBhMCdXMxCzAJBgNVBAgMAkNBMQwwCgYDVQQKDANpZHAxDDAKBgNVBAMMA2lkcDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1mKmlbr/SiHOhgdROpYeze96mw0WbO+BdJYDceeuNkaw0zOUCKZI6TNgrNsqEnLOyWYy5ywA9XA6Ni2qQTuKqapsMT3I1s9DMUg2ln7tTzNdhE02fY4GVjiCw7i9YJ+cgcMZh8qL0yoilrLpRLzLrRC6rApqYfEwn+5FPKtTt7cCAwEAAaNQME4wHQYDVR0OBBYEFNvFMRtHJ4DdbRbxhWceXnwd0MB8GA1UdIwQYMBaAFNvFMRtHJ4DdbRbxhWceXnwd0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQENBQADgYEAX0I5zpGqI7vzzs8CDyokux1JZzfu+O3P5GfOwUaIG9y01FzxgbL2MRKQoTXMAed97Q6vHA5cffvteu/rPcerpGmFj5h3wv5u+D0ch5s/Mk/Ug6S+x6k3CC+PkHimi6OEslFecDMhghUtPJAmhOGnTRwLr7hVeJXBHXWCTXA7aGE=/ds:XCertificate/ds:XData/ds:KeyInfo/md:KeyDescriptormd:NameIDFormaturn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress/md:NameIDFormatmd:SingleSignOnServiceBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"Location="