php 解析 saml协议,SAML2.0 协议初识(二)---Service Provider(SP)

上一节,我们初步认识了 SAML 协议的概念和工作流程,这一节将介绍 SP 端的一些细节。

通常情况下,SP 端是请求发起端,即当用户访问 SP 端的受保护资源时,由 SP 端向认证中心(IDP 端)发起认证请求。最终请求会回到 SP 端并由 SP 端将受保护资源授权给用户。

假设,SP 有一受保护静态资源 index.html,通常情况下,为了保护该静态资源,SP 可以选择用过滤器对访问该资源的请求进行过滤,如果该用户已被授权,则将 index.html 返回给用户;否则将生成认证请求到 IDP。

首先,我们先看一个有 SP 端生成的认证请求参数,它是普通的 xml 文档:

1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>

2

3 http://localhost:8080/sp

4

5

该请求根节点是 来表明是一个认证请求,有如下几个参数:

1、AssertionConsumerServiceURL断言消费服务地址,即当 IDP 认证成功后响应返回的地址

2、Destination目标地址,即 IDP 接收请求的地址

3、ID该请求的唯一标识

4、IssueInstant请求的时间

5、ProtocolBindingSP 声明此次通信的绑定方式,不同的绑定方式意味着不同的通信流程,SAML2.0 主要包括:HTTP-Artifact,HTTP-POST,HTTP-Redirect,SOAP 等几种绑定方式。

6、Version版本号

7、saml:IssuerSP 的 Id 标识

8、samlp:NameIDPolicyIDP 对于用户身份的标识;NameID policy 是 SP 关于 NameID 是如何被创建的说明;Format 指明 SP 需要返回什么类型的标识(SAML Artifact);属性AllowCreate指明 IDP 是否被允许当发现用户不存在时创建用户账号。

创建 AuthnRequest 对象采用了开源的 opensaml,代码如下:

1 /**

2 * 创建AutheRequest对象 *@paramidpSsoUrl3 *@paramacsUrl4 *@paramspEntityId5 *@return

6 */

7 publicAuthnRequest createRequest(String idpSsoUrl,String acsUrl,String spEntityId){8 AuthnRequest authnRequest = create(AuthnRequest.class,AuthnRequest.DEFAULT_ELEMENT_NAME);9 authnRequest.setIssueInstant(newDateTime());10 authnRequest.setDestination(idpSsoUrl);11 authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);12 authnRequest.setID(UUID.randomUUID().toString());13 authnRequest.setAssertionConsumerServiceURL(acsUrl);14

15 Issuer issuer = create(Issuer.class,Issuer.DEFAULT_ELEMENT_NAME);16 issuer.setValue(spEntityId);17 authnRequest.setIssuer(issuer);18

19 NameIDPolicy nameIDPolicy = create(NameIDPolicy.class,NameIDPolicy.DEFAULT_ELEMENT_NAME);20 nameIDPolicy.setAllowCreate(true);21 nameIDPolicy.setFormat(NameID.UNSPECIFIED);22 authnRequest.setNameIDPolicy(nameIDPolicy);23 returnauthnRequest;24 }

生成对象后转化成字符串:

1 Document document =asDOMDocument(authnRequest);2 DOMSource source=newDOMSource(document);3 TransformerFactory tf =TransformerFactory.newInstance();4 Transformer former=tf.newTransformer();5 former.setOutputProperty(OutputKeys.STANDALONE, "yes");6 StringWriter sw = newStringWriter();7 StreamResult sr = newStreamResult(sw);8 former.transform(source, sr);9 String result=sw.toString();

将 xml 字符串进行 base64 编码后拼接成认证请求地址发起认证请求,认证请求地址示例如下:

http://localhost:8080/idp/sso?SAMLRequest=fZJdT8IwFIb/SnPuy7qhwBqGQYmRxA8i0wvvSneQJl07ezo//r1zQKKJets+ed+e53R69l5b9oqBjHcFpAMBDJ32lXHPBTyUl3wCjKJylbLeYQHOw9lsSqq2jZy3cefu8aVFiqzLcST7iwLa4KRXZEg6VSPJqOV6fnMts4GQTfDRa2+BzYkwxK74wjtqawxrDK9G48P9dQG7GBuZJNZrZXeeopyIiUioSfQBBrboeo1TsX/677ypmoTIA1suCsiHW9SjVPBTvVX8JB/lPNfVho+z0ViMhgKHm9OOJGpx6b6GjgVkIh3zNONZWopcZpnMJgMhTp6ArQ5znBu3t/Xf0Js9RPKqLFd8dbcugT0erXcA7J3Kvjx8k/l/rDoahNlfvqbJt+Dj5m67pOVi5a3RH2xurX+7CKhit98YWgR26UOt4t/d6SDtT0zFtz0qW0cNarM1WEEy25f+/CGzTw==

后续就是 IDP 收到该请求后解析、认证、返回的过程了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值