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

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

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

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

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://localhost:8080/sp/consumer" Destination="http://localhost:8080/idp/sso"
ID="3983b844-5f42-4c66-b476-f69704f00b5b" IssueInstant="2017-12-21T08:35:56.975Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://localhost:8080/sp</saml:Issuer>
<samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/>
</samlp:AuthnRequest>

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

1、 AssertionConsumerServiceURL 断言消费服务地址,即当 IDP 认证成功后响应返回的地址
2、 Destination 目标地址,即 IDP 接收请求的地址
3、 ID 该请求的唯一标识
4、 IssueInstant 请求的时间
5、 ProtocolBinding SP 声明此次通信的绑定方式,不同的绑定方式意味着不同的通信流程,SAML2.0 主要包括:HTTP-Artifact,HTTP-POST,HTTP-Redirect,SOAP 等几种绑定方式。
6、 Version 版本号
7、 saml:Issuer SP 的 Id 标识
8、 samlp:NameIDPolicy IDP 对于用户身份的标识;NameID policy 是 SP 关于 NameID 是如何被创建的说明;Format 指明 SP 需要返回什么类型的标识(SAML Artifact);属性AllowCreate指明 IDP 是否被允许当发现用户不存在时创建用户账号。

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

 /**
* 创建AutheRequest对象 * @param idpSsoUrl
* @param acsUrl
* @param spEntityId
* @return
*/
public AuthnRequest createRequest(String idpSsoUrl,String acsUrl,String spEntityId){
AuthnRequest authnRequest = create(AuthnRequest.class,AuthnRequest.DEFAULT_ELEMENT_NAME);
authnRequest.setIssueInstant(new DateTime());
authnRequest.setDestination(idpSsoUrl);
authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI);
authnRequest.setID(UUID.randomUUID().toString());
authnRequest.setAssertionConsumerServiceURL(acsUrl); Issuer issuer = create(Issuer.class,Issuer.DEFAULT_ELEMENT_NAME);
issuer.setValue(spEntityId);
authnRequest.setIssuer(issuer); NameIDPolicy nameIDPolicy = create(NameIDPolicy.class,NameIDPolicy.DEFAULT_ELEMENT_NAME);
nameIDPolicy.setAllowCreate(true);
nameIDPolicy.setFormat(NameID.UNSPECIFIED);
authnRequest.setNameIDPolicy(nameIDPolicy);
return authnRequest;
}

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

 Document document = asDOMDocument(authnRequest);
DOMSource source=new DOMSource(document);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer former=tf.newTransformer();
former.setOutputProperty(OutputKeys.STANDALONE, "yes");
StringWriter sw = new StringWriter();
StreamResult sr = new StreamResult(sw);
former.transform(source, sr);
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 收到该请求后解析、认证、返回的过程了

最新文章

  1. Node.js:DNS模块的使用
  2. Cacti修改采集精度为1分钟
  3. nginx--配置https服务器
  4. JDBC操作MySQL数据库案例
  5. Js综合笔记
  6. mysql存储emoji表情
  7. Nginx模块开发时unknown directive &quot;echo&quot;的处理
  8. 4、第4次课 CSS代码第三节课20150923
  9. SpringMVC中使用zTree
  10. LeetCode 695. Max Area of Island (岛的最大区域)
  11. HTML 5 &lt;embed&gt; 标签
  12. 我对面向对象设计的理解——Java接口和Java抽象类
  13. C#组件系列——又一款日志组件:Elmah的学习和分享
  14. SDL 库 无法解析的外部符号 __imp__fprintf
  15. Centos 02 操作系统 &amp; Linux安装
  16. Linq.js表达式常见写法
  17. 阅读&lt;All Digital VCXO Replacement for Gigabit Transceiver Applications&gt;笔记(2)---XAPP589
  18. fedora、centos、rhel安装Adobe Flash Player 28
  19. 简单了解如何使用vue-router和vue-resource
  20. C:\WINDOWS\system32\drivers\etc\hosts 文件的作用

热门文章

  1. jquery元素节点操作
  2. tensorflow c++接口的编译安装与一些问题记录
  3. http://www.cnblogs.com/zhengyun_ustc/p/55solution2.html
  4. 关于C#中async/await中的异常处理(上)
  5. CardLayout使用
  6. 【转】Android之Adapter用法总结
  7. 利用U盘启动,全新安装Mac操作系统.
  8. openerp js调用Python类方法
  9. 【Datastage】函数大全
  10. Apache James 发送邮件到外网