OpenSAML2.X 在SSO系统中的应用

来源:互联网 发布:游戏本编程怎么样 编辑:程序博客网 时间:2024/05/21 16:57

背景

年底的时候有机会开发一个SPA(单页面应用)的项目,那时候需要用到票据的方式能够用Cookie的方式来登录。当是想到了OpenID或者是CAS的方式来做统一认证中心,后来一个安全界的大牛推荐让我用SAML,就走上了一条SAML路。后来由于个人原因离开了那个SPA项目,离开的时候SAML还没有开始做,只是大致上了解一些,后来在工作之余还是把OpenSAML2.X 完善成项目。 
项目地址:https://github.com/MrsSunny/SSO-OpenSAML

项目介绍

OpenSAML在网上的资料也不是很多,在国内用到的应该也不是很多,自己摸索着做了一下,有可能自己对OpenSAML的理解不够到位 
有一起研究的同学发邮箱到liuzhenx@hotmail.com一起学习,如果有错误的地方欢迎指正。 非常感谢。

项目准备

安装Java 
安装Maven 
安装Eclipse

Maven 配置

配置OpenSAML 依赖 
(具体的maven配置可以参考我GitHub上的项目)

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">dependency</span>></span>    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">groupId</span>></span>org.opensaml<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">groupId</span>></span>    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">artifactId</span>></span>opensaml<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">artifactId</span>></span>    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">version</span>></span>2.6.4<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">version</span>></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">dependency</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

使用方式

OpenSAML提供了几种方式来实现SSO之间SAML数据传输。本文主要对HTTP Artifact Binding 做个简单介绍

项目流程

1.用户访问SP的受保护资源 
2.SP检查是否有用户的Session,如果用则直接访问 
3.如果没有Session上下文SP随机生成Artifact,并生成AuthnRequest 
如果在Cookie中发现票据信息,把票据信息放到AuthnRequest当中 
4.SP建立Artifact与AuthnRequest的关联信息 
5.SP重定向到IDP的接受Artifact接口,用Get方式发送Artifact,和SP在IDP中的注册ID 
6.IDP接受Artifact,然后用HTTP POST方式来请求SP的getAuthnRequest接口(参数为Artifact) 
7.SP 接受到IDP传过来的Artifact ,根据Artifact 把关联的AuthnRequest返回给IDP 
8.IDP接受到getAuthnRequest然后来验证AuthnRequest的有效性,检查 Status Version 等信息,如果Cookie中的票据不为空,则检查票据是否正确,是否在有效期内,如果票据为空,则重定向用户到登录页面来提交信息。 
9.如果票据正确或者用户通过输入用户名密码等信息通过验证,则IDP生成Artifact对象,IDP生成Response对象,并根据用户信息生成断言,同时对Response 中的 断言做签名处理,对票据对象做加密和签名处理,并把票据信息写入Cookie,并建立Artifact与Response的关联关系,并重定向浏览器到SP的getArtifact接口 
10. SP 接受到Artifact,并通过HTTP POST的方式把Artifact发送到IDP 
11. IDP通过Artifact找到关联的Response对象返回给SP 
12.SP接受到IDP传输过来的Response对象,首先对Response中的断言做验签操作,如果通过,则同意用户访问资源。

⚠️:其实对于SP和IDP而言重要的信息其实是AuthnRequest和Response,只不过每次传输到浏览器的时候都是传递的是各自的引用,然后SP和IDP再更具饮用来获取 真实的数据。这样做安全性可能更高一点,但是增加了SP和IDP之间的通信。

⚠️:其中用到的证书都是自己用OpenSSL自己制定。 
参考地址:http://blog.csdn.net/howeverpf/article/details/21622545

SP端发送Artifact的JSP页面

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span>    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">form</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">action</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"<%=SysConstants.IDPRECEIVESPARTIFACT_URL%>"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">method</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"get"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span> = "<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">autoForm</span>"></span>        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">input</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"hidden"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"artifact"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">value</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"<%=request.getAttribute(SysConstants.ARTIFACT_KEY)%>"</span> /></span>        <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">input</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"hidden"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"token"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">value</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"<%=request.getAttribute(SysConstants.TOKEN_KEY)%>"</span> /></span>    <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">form</span>></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"text/javascript"</span>></span><span class="javascript" style="box-sizing: border-box;">    document.autoForm.submit();</span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

IDP 端接收Artifact的代码

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取Artifact</span>    String artifactBase64 = request.getParameter(SysConstants.ARTIFACT_KEY);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == artifactBase64) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SP端传递的Artifact参数错误,该参数不可为空"</span>);    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> ArtifactResolve artifactResolve = samlService.buildArtifactResolve();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Artifact artifact = (Artifact) samlService.buildStringToXMLObject(artifactBase64);    artifactResolve.setArtifact(artifact);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 对artifactResolve对象进行签名操作</span>    samlService.signXMLObject(artifactResolve);    String artifactParam = samlService.buildXMLObjectToString(artifactResolve);    String postResult = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根据Artifact信息从SP中获取Auth Request信息</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {      postResult = HttpUtil.doPost(SysConstants.SP_ARTIFACT_RESOLUTION_SERVICE, artifactParam);    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"访问SP端的:"</span> + SysConstants.SP_ARTIFACT_RESOLUTION_SERVICE + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"服务错误"</span> + e.getMessage());    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == postResult || <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>.equals(postResult)) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"redirect:/loginPage"</span>;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> ArtifactResponse artifactResponse = (ArtifactResponse) samlService.buildStringToXMLObject(postResult);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Status status = artifactResponse.getStatus();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == status) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"客户端的Status不能为空"</span>);    }    StatusCode statusCode = status.getStatusCode();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == statusCode) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取statusCode"</span>);    }    String codeValue = statusCode.getValue();    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 判断SAML的StatusCode</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (codeValue == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> || !codeValue.equals(StatusCode.SUCCESS_URI)) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取codeValue, 认证失败, SP端数据错误"</span>);    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String inResponseTo = artifactResponse.getInResponseTo();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String artifactResolveID = artifactResolve.getID();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == inResponseTo || !inResponseTo.equals(artifactResolveID)) {      logger.error(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"artifact的值和接收端的inResponseTo的值不一致,认证错误"</span>);      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"artifact的值和接收端的inResponseTo的值不一致,认证错误"</span>);    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> AuthnRequest authnRequest = (AuthnRequest) artifactResponse.getMessage();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (authnRequest == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取AuthRequest数据,认证错误"</span>);    }    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取SP的消费URL,下一步回调需要用到</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String customerServiceUrl = authnRequest.getAssertionConsumerServiceURL();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == customerServiceUrl) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取customerServiceUrl,SP端数据错误"</span>);    }    request.setAttribute(SysConstants.ACTION_KEY, customerServiceUrl);    HttpSession session = request.getSession(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);    session.setAttribute(SysConstants.ACTION_KEY, customerServiceUrl);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> SAMLVersion samlVersion = authnRequest.getVersion();    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 判断版本是否支持</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == samlVersion || !SAMLVersion.VERSION_20.equals(samlVersion)) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SAML版本错误,只支持2.0"</span>);    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Issuer issuer = authnRequest.getIssuer();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String appName = issuer.getValue();    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 判断issure的里面的值是否在SSO系统中注册过</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> App app = appService.findAppByAppName(appName.trim());    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (app == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"不支持当前系统: "</span> + appName);    }    Subject subject = authnRequest.getSubject();    NameID nameID = subject.getNameID();    String ticket = nameID.getValue();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>.equals(ticket) || <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == ticket) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"redirect:/loginPage"</span>;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {      ticket = URLDecoder.decode(ticket, SysConstants.CHARSET);    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (UnsupportedEncodingException e) {      e.printStackTrace();    }    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**     * 解密ticket     */</span>    PrivateKey privateKey = samlService.getRSAPrivateKey();    String[] afterDecode = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] ticketArray = Base64.decode(ticket);      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] decryptTicketArray = RSACoder.INSTANCE.decryptByPrivateKey(privateKey, ticketArray);      String decryptTicket = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> String(decryptTicketArray);      afterDecode = decryptTicket.split(SysConstants.TICKET_SPILT);    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"redirect:/loginPage"</span>;    }    logger.debug(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ticket验证痛过"</span>);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 判断令牌是否过期,如果令牌过期则直接</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (afterDecode == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> || afterDecode.length != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"redirect:/loginPage"</span>;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> expireTime = Long.parseLong(afterDecode[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> nowTime = System.currentTimeMillis();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (expireTime < nowTime) {      logger.debug(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Token已过期"</span>);      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"redirect:/loginPage"</span>;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Artifact idpArtifact = samlService.buildArtifact();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Response samlResponse = samlService.buildResponse(UUIDFactory.INSTANCE.getUUID());    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> id = Long.parseLong(afterDecode[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]);    User user = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> User();    user.setId(id);    user.setEmail(afterDecode[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]);    samlService.addAttribute(samlResponse, user);    SSOHelper.INSTANCE.put(idpArtifact.getArtifact(), samlResponse);    request.setAttribute(SysConstants.ARTIFACT_KEY, samlService.buildXMLObjectToString(idpArtifact));    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/saml/idp/send_artifact_to_sp"</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li></ul>

SP接受Artifact的代码

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    String spArtifact = request.getParameter(SysConstants.ARTIFACT_KEY);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == spArtifact) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取IDP端传过来的Artifact"</span>);    }    ArtifactResolve artifactResolve = samlService.buildArtifactResolve();    Artifact artifact = (Artifact) samlService.buildStringToXMLObject(spArtifact);    artifactResolve.setArtifact(artifact);    samlService.signXMLObject(artifactResolve);    String requestStr = samlService.buildXMLObjectToString(artifactResolve);    String postResult = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {      postResult = HttpUtil.doPost(SysConstants.IDP_ARTIFACT_RESOLUTION_SERVICE, requestStr);    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {      e.printStackTrace();      logger.error(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"访问IDP的"</span> + SysConstants.IDP_ARTIFACT_RESOLUTION_SERVICE + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"服务错误"</span>);    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == postResult) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"从"</span> + SysConstants.IDP_ARTIFACT_RESOLUTION_SERVICE + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"服务获取的数据为空,请检查IDP端数据格式"</span>);    }    ArtifactResponse artifactResponse = (ArtifactResponse) samlService.buildStringToXMLObject(postResult);    SAMLObject samlObject = artifactResponse.getMessage();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == samlObject) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取Response信息"</span>);    }    Response samlResponse = (Response) samlObject;    List<Assertion> assertions = samlResponse.getAssertions();    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == assertions || assertions.size() == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取断言,请重新发起请求!!!"</span>);    }    Assertion assertion = samlResponse.getAssertions().get(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (assertion == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {      request.setAttribute(SysConstants.ERROR_LOGIN, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);    } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {      <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**       * 验证签名       */</span>      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> signSuccess = samlService.validate(assertion);      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!signSuccess) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"验证签名错误"</span>);      }      HttpSession session = request.getSession(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);      List<AttributeStatement> arrtibuteStatements = assertion.getAttributeStatements();      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == arrtibuteStatements || arrtibuteStatements.size() == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取属性列表,请重新发起请求"</span>);      }      AttributeStatement attributeStatement = assertion.getAttributeStatements().get(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);      List<Attribute> list = attributeStatement.getAttributes();      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> == list) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RuntimeException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"无法获取属性列表IDP端错误"</span>);      }      User user = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> User();      list.forEach(pereAttribute -> {        String name = pereAttribute.getName();        XSString value = (XSString) pereAttribute.getAttributeValues().get(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);        String valueString = value.getValue();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (name.endsWith(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Name"</span>)) {          user.setName(valueString);        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (name.equals(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Id"</span>)) {          user.setId(Long.parseLong(valueString));        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (name.equals(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"LoginId"</span>)) {          user.setLogin_id(valueString);        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (name.equals(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Email"</span>)) {          user.setEmail(valueString);        }      });      session.setAttribute(SysConstants.LOGIN_USER, user);      putAuthnToSecuritySession(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"admin"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"admin"</span>);      request.setAttribute(SysConstants.ERROR_LOGIN, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li></ul>

学习目标

感觉自己认识的不够全面,希望有同学一起研究一下,特别是SP端发送Auth Request的时候,应该带上什么数据,票据是否在这个阶段发送,以及怎么发送,有兴趣的同学可以把GitHub告诉我一起来完善这个项目。

0 0
原创粉丝点击