1. 用户尝试获得权限

流程首先从一个非认证的用户开始,该用户尝试从一个受保护的SP那里获得访问权限。某种方式的过滤器被设置在访问路径上来检测用户是否被授权(J2ee中servlet类就是一个很好地例子)。这一部分其实并不是SAML协议里的内容,但是却决定了是否要被授权。

2. 用户被重定向到IDP

当访问路径上被设置的过滤器发现用户并非是被认证的,将会自动把用户从定向到IDP,以求验证用户的身份。

3. 用户被认证

在这一步里,用户被认证。注意这里并没任何涉及到SP的交互,在安全方式内,IDP对于认证用户有着全权责任。

4. 已认证的用户被从定向回SP

当用户被认证成功之后,用户会携带着SAML产物(SAML artifact)被从定向回SP。这样的SAML产物也可以说是认证信息的标识,因为认证信息中有敏感的信息不能直接通过浏览器传输,所以这里只是发送标识而已。

5. 要求认证信息

当收到SAML产物之后,SP将其发送回IDP,IDP依据SAML产物找到认证信息,并通过SAML产物响应(SAML Artifact Response)发送回SP

上面提到的SAML产物响应(SAML Artifact Response) 中就包含SAML断言,它就是认证的证据。断言中最重要的数据就该用户什么时候以什么方式被认证的。

OpenSAML 快速上手

说了这么多理论上的流程,现在开始讲讲OpenSAML这个库的构成和使用。

如何添加OpenSAML库

OpenSAML3是由Maven组织的多模块库,每个模块的功能各不相同。由于项目功能越来越丰富,对于现在的用户已经不可能通过一个单一的依赖来引用其所有的功能了。每个模块都需要添加自己都得引用。OpenSAML最新版的模块列表如下:

• opensaml-core

• opensaml-profile-api

• opensaml-profile-impl

• opensaml-soap-api

• opensaml-soap-impl

• opensaml-saml-api

• opensaml-saml-impl

• opensaml-xacml-api

• opensaml-xacml-impl

• opensaml-xacml-saml-api

• opensaml-xacml-saml-impl

• opensaml-messaging-api

• opensaml-messaging-impl

• opensaml-storage-api

• opensaml-storage-impl

• opensaml-security-api

• opensaml-security-impl

• opensaml-xmlsec-api

• opensaml-xmlsec-impl

用户可以根据自己项目的情况自行添加需要的模块,Maven中具体引用的信息如下:

org.opensaml

opensaml-core

3.2.0

org.opensaml

opensaml-saml-api

3.2.0

org.opensaml

opensaml-saml-impl

3.2.0

org.opensaml

opensaml-messaging-api

3.2.0

org.opensaml

opensaml-messaging-impl

3.2.0

org.opensaml

opensaml-soap-api

3.2.0

org.opensaml

opensaml-soap-impl

3.2.0

Shibboleth repo

https://build.shibboleth.net/nexus/content/repositories/releases

保证JCE实现的正确性

OpenSAML使用JCE来提供密码学的功能模块。由于某些

JCE的实现并不覆盖所有OpenSAML要求的功能,所以推荐使用Bouncy Castle的JCE实现。

为了帮助用户来确认JCE的实现是否正确,可以使用如下函数:

JavaCryptoValidationInitializer javaCryptoValidationInitializer =

newJavaCryptoValidationInitializer();

javaCryptoValidationInitializer.init();

这个方法应该在OpenSAML初始化之被调用,来确保当前的环境可以符合要求。

如下方法可以用来打印当前已经被安装的所有JCE的provider:

for(Provider jceProvider : Security.getProviders()) {

logger.info(jceProvider.getInfo());

}

使用Maven引用OpenSAML时,Bouncy Castle

provider将会被自动引用。如果是手动下载OpenSAML源码依赖,其中也已经包括了Bouncy Castle

provider,但是需要手动添加到class path中。

日志打印

OpenSAML使用SLF4J管理日志信息。虽然SLF4J本身没有任何打印日志的能力,但是其依赖于其他logging的实现来做日志管理。OpenSAML团队选择使用Logback来实现logging功能(其他的实现也可以)。

为了能使用LogBack,需要添加依赖包:

logback-core

logback-classic

apache commons logging

或者直接添加Maven依赖:

ch.qos.logback

logback-core

1.0.13

ch.qos.logback

logback-classic

1.0.13

ch.qos.logback

logback-classic

1.0.13

commons-logging

commons-logging

1.2

OpenSAML初始化过程

OpenSAML的初始化依赖于一些列配置文件。OpenSAML已经有一个默认的配置,其已经可以满足大多数的使用需求,如果有需要还可以对其修改。

配置文件必须在OpenSAML使用之前被加载,加载默认配置需的方法如下进行:

InitializationService.initialize();

这之后,OpenSAML库才能正常使用;

如果不加载配置文件,OpenSAML的初始化将不能完成,其无法返回某个Obejct,返回NullPointerException。这是一个常见的错误。

创建SAML对象

SAML对象的创建使用了工厂模式和构建者模式,涉及到链式配置和类型准换。

创建SAML断言对象的方法如下:

XMLObjectBuilderFactory builderFactory =XMLObjectProviderRegistrySupport.getBuilderFactory();

Assertion assertion=(Assertion) builderFactory

.getBuilder(Assertion.DEFAULT_ELEMENT_NAME)

.buildObject(Assertion.DEFAULT_ELEMENT_NAME);

为了避免大量不需要的代码,使用泛型的工具方法是一个好主意。可以通过如下方法生成不同类型的对象:

public static T buildSAMLObject(final Classclazz) {

XMLObjectBuilderFactory builderFactory=XMLObjectProviderRegistrySupport.getBuilderFactory();

QName defaultElementName=(QName) clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null);

T object=(T) builderFactory.getBuilder(defaultElementName)

.buildObject(defaultElementName);returnobject;

}

通过使用上面的方法,就可以将生成断言对象的代码简化为一行;

OpenSAMLUtils.buildSAMLObject(Assertion.class);

实例项目

为了方便读者理解和后续文章的解读,这里提供一个示例项目:一个很简单的网址,其充当SP;同时该项目还包括一个很简单的IDP;

SAML协议的交互将在这二者之间展开。

mvn tomcat:run

嵌入项目中的Tomcat就会启动,运行成功时会有如下信息:

INFO: Starting Coyote HTTP/1.1 on http-8080

经过本人的修改,该项目可以在IntelliJ Idea以工程模式打开,运行方式设置为mvn,命令是tomcat:run。这就便于读者调试和修改。

5045e6a377678d51b3e96d5507fed713.png

e3885e0f90ac2126090dad6003f1bc70.png

点击“Authenticate”按钮将通过认证,并重定向回SP,

910001d0f5ff7d1dd25899dd55f1e34e.png

到此为止整个SAML协议的流程及完成了,相关日志信息会在控制台中输出。

作者:登高且赋

链接:https://www.jianshu.com/p/d041935641b4

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐