【揭秘SAML协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略Saml协议的奥秘,告别SSO的迷茫与困惑

简介: SAML(Security Assertion Markup Language)是由OASIS制定的基于XML的开放标准。它用于在身份提供者(IdP)和服务提供者(SP)之间交换身份验证和授权数据,从而支持跨域单点登录,提高身份认证和授权管理的安全性和效率。

注意:特此声明:本文首发在掘金:https://juejin.cn/post/7330680498686214180,未经允许,请勿进行侵权私自转载

SAML协议简介

SAML(Security Assertion Markup Language)是由OASIS制定的基于XML的开放标准。它用于在身份提供者(IdP)和服务提供者(SP)之间交换身份验证和授权数据,从而支持跨域单点登录,提高身份认证和授权管理的安全性和效率。

SAML作用和效果

SAML在Web-based单点登录(SSO)中发挥着至关重要的作用。借助SAML,用户只需进行一次身份验证,即可访问多个不同的应用程序或服务,而无需重复输入凭证。这种集中化的身份验证和授权机制不仅提高了用户体验,还增强了安全性。现在,让我们进一步探讨SAML的工作原理。

为什么要使用SAML

在这里插入图片描述
首先,使用SAML可以显著提升用户体验。通过实现单点登录(SSO),用户只需进行一次身份验证,即可访问多个不同的系统服务。这意味着用户无需分别记忆多个系统的用户名和密码,只需记住一个即可。

其次,使用SAML还有助于提高系统的安全性。在SAML框架下,我们只需向身份提供者(IdP)提供用户名和密码进行身份验证,而无需将这些信息存储在每个资源服务器上。这样,认证信息的安全性得到了保障,因为它们仅在IdP中存储了一份。

最后,通过集中存储和管理用户的认证信息,SAML还有助于降低系统的复杂性。

SAML角色组成

在SAML协议中,有三个核心角色:主体(principal)、身份提供者(Identity Provider,简称IdP)和服务提供者(Service Provider,简称SP)。
在这里插入图片描述

  • 主体(principal)通常代表人类用户/浏览器终端
  • IdP主要负责进行身份认证,并将用户的认证信息和授权信息传递给SP。
  • SP的主要职责是验证用户的认证信息,并授权用户访问指定的资源信息。

通过这样的角色划分和分工,SAML协议能够有效地支持跨域单点登录,提高身份认证和授权管理的安全性和效率。

SAML是怎么工作

通过一个详细的流程图来深入了解SAML如何实现SSO认证。请注意,根据请求方式的不同(重定向和POST),SAML的认证流程略有差异。

首先,我们来看看通过重定向方式进行的SAML SSO认证流程:
在这里插入图片描述

  1. 用户尝试访问受保护的资源(例如某个应用或服务)。
  2. 服务提供者(SP)识别出用户未经过身份验证,并重定向用户到身份提供者(IdP)进行身份验证。
  3. 用户在IdP的网站上输入用户名和密码进行身份验证。
  4. IdP验证用户信息,并将包含身份验证和授权信息的SAML响应发送回SP。
  5. SP验证SAML响应,并授予用户访问受保护资源的权限。

接下来,我们来看看通过POST方式进行的SAML SSO认证流程:
在这里插入图片描述

  1. 用户尝试访问受保护的资源。
  2. SP识别出用户未经过身份验证,并生成包含重定向URL的SAML请求的HTML表单。
  3. SP将HTML表单发送给用户,要求用户填写用户名和密码。
  4. 用户在表单中输入用户名和密码,并提交给IdP进行身份验证。
  5. IdP验证用户信息,并将包含身份验证和授权信息的SAML响应发送回SP。
  6. SP验证SAML响应,并授予用户访问受保护资源的权限。

通过以上两种方式,我们可以看到SAML通过在IdP和SP之间交换身份验证和授权信息,实现了SSO认证,从而简化了用户的登录过程,提高了系统的安全性。

核心协议详解

上面中用户可以理解为web浏览器,我们看一下如果用户想请求SP服务提供者的资源的时候,SAML协议是怎么处理的。

  1. 用户通过用户请求SP服务提供者,比如:https://www.xx.xx.com,在SP接收到请求后,它会进行必要的安全检查。如果发现已经存在一个有效的安全上下文,SP直接进入最后一步,继续处理请求。

  2. 在上一步中,如果SP没有找到有效的安全上下文,它会生成对应的SAML请求,并通过重定向用户代理(User Agent)将用户转至IdP,以确保用户能够通过身份验证并获得访问受保护资源的权限。

    • 通过与IdP的交互,用户可以完成身份验证,并获得必要的授权信息,以便于之后访问受保护的资源。

      302 Redirect
      Location: https://idp.xxxx.com/SAML2/SSO/Redirect?SAMLRequest=request&RelayState=token
      

      RelayState标志

在SAML协议中,RelayState是一个重要的组成部分,主要用于防范CSRF攻击。RelayState是SP(服务提供者)维护的一个状态信息。简单来说,它就像是一个“凭证约定”,帮助SP追踪用户的请求,并确保请求是从合法的来源发送的。

跨站请求伪造(Cross-Site Request Forgery,简称CSRF) 是一种常见的网络攻击手段。攻击者诱导受害者在不知情的情况下执行恶意请求,通常是为了在受害者的身份下进行非法操作。

RelayState在防范CSRF攻击中的具体操作

在这里插入图片描述

  • 请求的追踪:当用户从一个应用或服务(例如,SP)发送请求到另一个应用或服务(例如,IdP)进行身份验证时,SP会将一个特定的RelayState参数附加到请求中。这个RelayState参数包含了一个唯一的标识符或令牌,用于标识这个特定的请求。
  • 验证返回的请求:当IdP完成身份验证后,它会将用户重定向回SP,并附带原始的RelayState参数。SP接收到请求后,会检查返回的RelayState参数是否与原始请求中的匹配。
    • 如果匹配,说明请求是合法的;
    • 如果不匹配,则很可能是CSRF攻击。

SAMLRequest请求体

在SAML协议中,元素是用于身份验证请求的XML元素,它包含了发起身份验证请求所需的必要信息,SAMLRequest是经过Base64编码的<samlp:AuthnRequest>,以下是一个samlp:AuthnRequest的示例:

<samlp:AuthnRequest
  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
  ID="id1234567890"
  Version="2.0"
  IssueInstant="2024-02-02T18:17:54Z"
  Destination="https://sp.example.com/SAML2/SSO/POST"
  ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST">
  <saml:Issuer>https://idp.example.com/SAML2</saml:Issuer>
  <samlp:NameIDPolicy
    Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
    AllowCreate="true"/>
  <samlp:RequestedAuthnContext Comparison="exact">
    <saml:AuthnContextClassRef>
      urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
    </saml:AuthnContextClassRef>
  </samlp:RequestedAuthnContext>
</samlp:AuthnRequest>

元素解释

  • <saml:Issuer>:标识发出请求的身份提供商(IdP)的实体ID。在这里,它是https://idp.example.com/SAML2
  • <samlp:NameIDPolicy>:定义了NameID策略,用于指定如何创建和管理NameID(用于标识用户的唯一名称)。在这里,Format属性指定了NameID的格式为“transient”,表示该NameID是临时的且仅在当前会话中有效。AllowCreate属性设置为“true”,表示允许创建新的NameID。
  • <samlp:RequestedAuthnContext>:指定了所请求的身份验证上下文,用于定义所需的身份验证方法或条件。在这里,Comparison属性设置为“exact”,表示请求的身份验证上下文必须与提供的身份验证上下文完全匹配。
  • <saml:AuthnContextClassRef>:元素指定了身份验证类别的引用,这里是“PasswordProtectedTransport”,表示使用受密码保护的传输来进行身份验证。

为了安全起见,SAMLRequest还可以使用SP提供的签名key来进行签名

用户重定向IDP数据信息

在接收到前一步的请求后,SP将RelayState和SAMLRequest进行整合,并通过HTTP 302重定向将用户(浏览器)引导至IdP的SSO服务器,请求的消息体如下:

GET /SAML2/SSO/Redirect?SAMLRequest=request&RelayState=token HTTP/1.1
Host: idp.xxxx.com

IdP在接收到AuthnRequest请求后,会进行严格的安全验证。如果验证通过,IdP会展示其登录界面,允许用户进行身份验证。用户可以输入用户名密码进行登录。

登录成功之后

在完成安全验证后,IdP将返回一个XHTML表单,该表单内嵌了经过Base64编码的SAMLResponse信息。SAMLResponse中包含了用户的相关数据,且同样以samlp:Response的形式进行编码。

<samlp:Response
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="identifier_2"
    InResponseTo="identifier_1"
    Version="2.0"
    IssueInstant="2023-01-05T09:22:05Z"
    Destination="https://sp.xxxx.com/SAML2/SSO/POST">
    <saml:Issuer>https://idp.xxxx.com/SAML2</saml:Issuer>
    <samlp:Status>
      <samlp:StatusCode
        Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion
      xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
      ID="identifier_3"
      Version="2.0"
      IssueInstant="2023-01-05T09:22:05Z">
      <saml:Issuer>https://idp.flydean.com/SAML2</saml:Issuer>
      <!-- a POSTed assertion MUST be signed -->
      <ds:Signature
        xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
      <saml:Subject>
        <saml:NameID
          Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">
          3f7b3dcf-1674-4ecd-92c8-1544f346baf8
        </saml:NameID>
        <saml:SubjectConfirmation
          Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
          <saml:SubjectConfirmationData
            InResponseTo="identifier_1"
            Recipient="https://sp.xxxx.com/SAML2/SSO/POST"
            NotOnOrAfter="2023-09-05T09:27:05Z"/>
        </saml:SubjectConfirmation>
      </saml:Subject>
      <saml:Conditions
        NotBefore="2023-09-05T09:17:05Z"
        NotOnOrAfter="2023-09-05T09:27:05Z">
        <saml:AudienceRestriction>
          <saml:Audience>https://sp.xxx.com/SAML2</saml:Audience>
        </saml:AudienceRestriction>
      </saml:Conditions>
      <saml:AuthnStatement
        AuthnInstant="2023-09-05T09:22:00Z"
        SessionIndex="identifier_3">
        <saml:AuthnContext>
          <saml:AuthnContextClassRef>
            urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
         </saml:AuthnContextClassRef>
        </saml:AuthnContext>
      </saml:AuthnStatement>

我们观察到samlp:Response中包含saml:Assertion信息,并且针对于相关的交互流程进行梳理
在这里插入图片描述

  1. 当用户代理收到XHTML表单后,它会将该表单提交给SP。
  2. 在SP中,断言消费者服务会处理该请求,创建相应的安全上下文,并重新定向用户代理至目标资源页面。
  3. 随后,用户代理再次请求SP资源,由于安全上下文已经建立,SP可以直接返回所需资源,而无需再次与IdP进行认证。

注意,上述信息交换完全由前端浏览器完成,SP与IdP之间不存在直接通信

如果为了提高安全性,也可以使用引用消息。也就是说IdP返回的不是直接的SAML assertion,而是一个SAML assertion的引用。SP收到这个引用之后,可以从后台再去查询真实的SAML assertion,从而提高了安全性。

相关文章
|
17天前
|
Java 容器
java集合框架复习----(1)
这篇文章提供了Java集合框架的复习资料,包括集合的概念、Collection接口的使用,以及如何通过代码示例演示集合的操作,如增加、删除元素,以及遍历集合元素。
java集合框架复习----(1)
|
12天前
|
安全 前端开发 Java
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择。依赖注入使对象管理交由Spring容器处理,实现低耦合高内聚;AOP则分离横切关注点如事务管理,增强代码模块化。Spring还提供MVC、Data、Security等模块满足多样需求,并通过Spring Boot简化配置与部署,加速微服务架构构建。掌握这些核心概念与工具,开发者能更从容应对挑战,打造卓越应用。
28 1
|
17天前
|
存储 安全 Java
java集合框架复习----(2)List
这篇文章是关于Java集合框架中List集合的详细复习,包括List的特点、常用方法、迭代器的使用,以及ArrayList、Vector和LinkedList三种实现类的比较和泛型在Java中的使用示例。
java集合框架复习----(2)List
|
17天前
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
1天前
|
存储 Java 程序员
Java中的集合框架:从入门到精通
【8月更文挑战第30天】在Java的世界里,集合框架是一块基石,它不仅承载着数据的存储和操作,还体现了面向对象编程的精髓。本篇文章将带你遨游Java集合框架的海洋,从基础概念到高级应用,一步步揭示它的奥秘。你将学会如何选择合适的集合类型,掌握集合的遍历技巧,以及理解集合框架背后的设计哲学。让我们一起探索这个强大工具,解锁数据结构的新视角。
|
23天前
|
存储 算法 Java
14 Java集合(集合框架+泛型+ArrayList类+LinkedList类+Vector类+HashSet类等)
14 Java集合(集合框架+泛型+ArrayList类+LinkedList类+Vector类+HashSet类等)
34 2
14 Java集合(集合框架+泛型+ArrayList类+LinkedList类+Vector类+HashSet类等)
|
2天前
|
存储 算法 Java
Java中的集合框架深度解析云上守护:云计算与网络安全的协同进化
【8月更文挑战第29天】在Java的世界中,集合框架是数据结构的代言人。它不仅让数据存储变得优雅而高效,还为程序员提供了一套丰富的工具箱。本文将带你深入理解集合框架的设计哲学,探索其背后的原理,并分享一些实用的使用技巧。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往高效编程的大门。
|
7天前
|
消息中间件 Java Kafka
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
|
17天前
|
存储 Java
java集合框架复习----(3)Set
这篇文章详细介绍了Java集合框架中的Set集合,包括HashSet和TreeSet的特点、实现原理和使用示例,展示了Set集合的无序性、元素唯一性以及如何通过自定义比较器实现元素的排序。
|
18天前
|
安全 前端开发 Java
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
在Web安全上下文中,源(Origin)是指一个URL的协议、域名和端口号的组合。这三个部分共同定义了资源的来源,浏览器会根据这些信息来判断两个资源是否属于同一源。例如,https://www.example.com:443和http://www.example.com虽然域名相同,但由于协议和端口号不同,它们被视为不同的源。同源(Same-Origin)是指两个URL的协议、域名和端口号完全相同。只有当这些条件都满足时,浏览器才认为这两个资源来自同一源,从而允许它们之间的交互操作。
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
下一篇
云函数