【Single Sign On】Domino平台应用与构异系统实现单点登录

本部分的描述仅适用于单一的Domino平台应用与构异系统实现单点登录。



*

1.1 Domino LTPA Cookie **生成原理**

在与 Domino SSO 的时候,会使用 LTPA Token的认证方式,本文描述它的生成原理,通过它我们可以自己编码生成身份认证的 cookie,实现 SSO

首先,这个 cookie 由以下部分组成:

·LTPA token 版本(4字节)

·创建时间(8字节)

·过期时间(8字节)

·用户名(可变长度)

·Domino LTPA 密钥(20字节)

接下来分别说明各部分的具体内容:

·LTPA token 版本目前 Domino 只有一种值:0x0001

·创建时间为以十六进制方式表示的Unix time,例如:2009-04-09 13:52:42 (GMT +8) =
1239256362 = 49DD8D2A

·过期时间=创建时间 + SSO 配置文档的过期时间(LTPA_TokenExpiration域)

·用户名为 Names 中用户文档的FullName域值;如:Squall Zhong/Digiwin

·Domino LTPA 密钥通过 Base64编码后,保存在 SSO 配置文档的LTPA_DominoSecret域中

http://lh6.googleusercontent.com/9aNb90qGxfI2xo079GBnZU70rVkt0VA0PptmOwkXa3lMWTC4NsYGlyN9SSs2KXnf-umJAFKFSBHwUYyHD89laYLElg

当然不能将密钥直接发送给浏览器,所以将上述部分合并起来(如上图),计算 SHA-1 校验和。

http://lh5.googleusercontent.com/XLW2lNbFKVzFhL7hGYHbYxQFFy9VqrMdND0CRWaPYL8UyKzjOl7cPTiIjY_sJ5mP8QSNeAFZLT-8slUCXqXHKpvGSQ

然后用 SHA-1 校验和替换掉 Domino LTPA 密钥,最后再将内容通过 Base64 编码,形成最终的 cookie 发送给浏览器(如上图)。这样如果 cookie 中的任何内容被修改,校验和就不对了,达到了防篡改的效果。所以最终LTPA
Cookie
所得到的值为以下公式组成:

SHA-1=LTPA**版本号+创建时间+过期时间+用户名+Domino LTPA 密钥**

LTPA Cookie= Base64(LTPA**版本号+创建时间+过期时间+用户名+SHA-1)**



*

1.2 **异构系统所需信息**

·Domino 所使用的DNS域,如:vgolive.com

·过期时间(分钟),如:30

·Domino LTPA 密钥

·Domino验证字名称,如:/O=VGOLive Technology

注:用户名可以通过Domino验证字进行拼接,如异构系统中用户名为SquallZhong,相应在Domino中的DN就是CN=SquallZhong/O=VGOLive
Technology
。此类情况仅限于Domino中的CN与异构系统中的用户名一致。如果不一致,需要异构系统做用户对应



*

1.3 **实现**

Base64解码/编码所需Jar包:apache-commons-codec-1.3.jar**以上**

SHA-1的校验使用java.security.MessageDigest

转换字符集使用:Cp850



*

1.3.1 **解析**

show source

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">01</span>    import <span lang="EN-US" style="font-size:12.0pt;color:#666666">org.apache.commons.codec.binary.Base64; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">02…... </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">03</span>final <span lang="EN-US" style="font-size:12.0pt;color:#666666">String CHARSET = </span>“Cp850”<span lang="EN-US" style="font-size:12.0pt;color:#666666">; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">04</span>byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] dominoSecret = Base64.decodeBase64(ltpaDominoSecret.getBytes()); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">05</span>byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] ltpa = Base64.decodeBase64(ltpaToken.getBytes()); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">06ByteArrayInputStream stream = </span>new <span lang="EN-US" style="font-size:12.0pt;color:#666666">ByteArrayInputStream(ltpa); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">07</span>int <span lang="EN-US" style="font-size:12.0pt;color:#666666">usernameLength = ltpa.length – </span>40<span lang="EN-US" style="font-size:12.0pt; color:#666666">; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">08</span>byte <span lang="EN-US" style="font-size:12.0pt;color:#666666">header[] = </span>new byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[</span>4<span lang="EN-US" style="font-size:12.0pt;color:#666666">]; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">09</span>byte <span lang="EN-US" style="font-size:12.0pt;color:#666666">creation[] = </span>new byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[</span>8<span lang="EN-US" style="font-size:12.0pt;color:#666666">]; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">10</span>byte <span lang="EN-US" style="font-size:12.0pt;color:#666666">expires[] = </span>new byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[</span>8<span lang="EN-US" style="font-size:12.0pt;color:#666666">]; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">11</span>byte <span lang="EN-US" style="font-size:12.0pt;color:#666666">username[] = </span>new byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[usernameLength]; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">12</span>byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] sha = </span>new byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[</span>20<span lang="EN-US" style="font-size:12.0pt;color:#666666">]; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">13// </span>``<span style="font-size:12.0pt; color:#666666">读取<span lang="EN-US">LTPAToken</span>版本号 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">14stream.read(header, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, </span>4<span lang="EN-US" style="font-size:12.0pt;color:#666666">); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">15</span>if <span lang="EN-US" style="font-size:12.0pt;color:#666666">(header[</span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">] != </span>0 <span lang="EN-US" style="font-size:12.0pt;color:#666666">|| header[</span>1<span lang="EN-US" style="font-size:12.0pt;color:#666666">] != </span>1 <span lang="EN-US" style="font-size:12.0pt;color:#666666">|| header[</span>2<span lang="EN-US" style="font-size:12.0pt;color:#666666">] != </span>2<span lang="EN-US" style="font-size:12.0pt;color:#666666">|| header[</span>3<span lang="EN-US" style="font-size:12.0pt;color:#666666">] != </span>3<span lang="EN-US" style="font-size:12.0pt;color:#666666">) </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">16</span>        throw new <span lang="EN-US" style="font-size:12.0pt;color:#666666">IllegalArgumentException(</span>“Invalid
ltpaToken format”
<span lang="EN-US" style="font-size: 12.0pt;color:#666666">); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">17</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">读取开始时间 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">18</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">stream.read(creation, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, </span>8<span lang="EN-US" style="font-size:12.0pt;color:#666666">); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">19</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">读取到期时间 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">20</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">stream.read(expires, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, </span>8<span lang="EN-US" style="font-size:12.0pt;color:#666666">); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">21</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">读取<span lang="EN-US">Domino</span>用户<span lang="EN-US">DN </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">22</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">stream.read(username, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, usernameLength); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">23</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">读取<span lang="EN-US">SHA</span>校验和 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">24</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">stream.read(sha, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, </span>20<span lang="EN-US" style="font-size:12.0pt;color:#666666">); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">25</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">转换用户名 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">26</span>   char <span lang="EN-US" style="font-size:12.0pt;color:#666666">characters[] = </span>new char<span lang="EN-US" style="font-size:12.0pt;color:#666666">[usernameLength]; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">27</span>   try <span lang="EN-US" style="font-size:12.0pt;color:#666666">{ </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">28</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">InputStreamReader isr = </span>new <span lang="EN-US" style="font-size:12.0pt;color:#666666">InputStreamReader( </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">29</span>            new <span lang="EN-US" style="font-size:12.0pt;color:#666666">ByteArrayInputStream(username), </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">30</span>            <span lang="EN-US" style="font-size:12.0pt;color:#666666">CHARSET); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">31</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">isr.read(characters); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">32</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">} </span>catch <span lang="EN-US" style="font-size:12.0pt;color:#666666">(Exception e) { </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">33</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">} </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">34</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">获得<span lang="EN-US">Domino</span>用户<span lang="EN-US">DN </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">35</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">String dn = </span>new <span lang="EN-US" style="font-size:12.0pt;color:#666666">String(characters); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">36</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">获得创建时间 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">37</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">Date creationDate = </span>new <span lang="EN-US" style="font-size:12.0pt;color:#666666">Date( </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">38</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">Long.parseLong(</span>new <span lang="EN-US" style="font-size:12.0pt;color:#666666">String(creation), </span>16<span lang="EN-US" style="font-size:12.0pt;color:#666666">) * </span>1000<span lang="EN-US" style="font-size:12.0pt;color:#666666">); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">39</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">获得到期时间 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">40</span>   <span lang="EN-US" style="font-size:12.0pt;color:#666666">Date expiresDate = </span>new <span lang="EN-US" style="font-size:12.0pt;color:#666666">Date( </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">41</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">Long.parseLong(</span>new <span lang="EN-US" style="font-size:12.0pt;color:#666666">String(expires), </span>16<span lang="EN-US" style="font-size:12.0pt;color:#666666">) * </span>1000<span lang="EN-US" style="font-size:12.0pt;color:#666666">); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">42…... </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">43// </span>``<span style="font-size:12.0pt; color:#666666">创建<span lang="EN-US">LTPA Token </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">44</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">ByteArrayOutputStream ostream = </span>new <span lang="EN-US" style="font-size:12.0pt;color:#666666">ByteArrayOutputStream(); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">45</span>    try <span lang="EN-US" style="font-size:12.0pt;color:#666666">{ </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">46</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// LTPA Token</span>``<span style="font-size:12.0pt;color:#666666">版本号 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">47</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">ostream.write(header); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">48</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">创建时间 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">49</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">ostream.write(creation); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">50</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">过期时间 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">51</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">ostream.write(expires); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">52</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// Domino</span>``<span style="font-size:12.0pt;color:#666666">用户<span lang="EN-US">DN</span>,如<span lang="EN-US">CN=SquallZhong/O=DigiWin </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">53</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">ostream.write(username); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">54</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// Domino LTPA </span>``<span style="font-size:12.0pt;color:#666666">密钥 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">55</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">ostream.write(dominoSecret); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">56</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">ostream.close(); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">57</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">} </span>catch <span lang="EN-US" style="font-size:12.0pt;color:#666666">(IOException e) { </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">58</span>        throw new <span lang="EN-US" style="font-size:12.0pt;color:#666666">RuntimeException(e); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">59</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">} </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">60</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">进行<span lang="EN-US"> SHA-1 </span>校验和 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">61</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">MessageDigest md; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">62</span>    try <span lang="EN-US" style="font-size:12.0pt;color:#666666">{ </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">63</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">md = MessageDigest.getInstance(</span>“SHA-1”<span lang="EN-US" style="font-size:12.0pt;color:#666666">); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">64</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">md.reset(); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">65</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">} </span>catch <span lang="EN-US" style="font-size:12.0pt;color:#666666">(NoSuchAlgorithmException e) { </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">66</span>        throw new <span lang="EN-US" style="font-size:12.0pt;color:#666666">RuntimeException(e); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">67</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">} </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">68</span>    byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] digest = md.digest(ostream.toByteArray()); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">69</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">完成<span lang="EN-US"> SHA-1 </span>校验和,<span lang="EN-US">digest</span>长度为<span lang="EN-US">20 </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">70</span>    boolean <span lang="EN-US" style="font-size:12.0pt;color:#666666">valid = MessageDigest.isEqual(digest, sha);</span>



*

1.3.2 **生成**

show source

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">01</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">/** </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">02</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">* </span>``<span style="font-size:12.0pt;color:#666666">为指定用户创建有效的<span lang="EN-US">LTPA Token.</span>创建时间为<span lang="EN-US">&lt;tt&gt;now&lt;/tt&gt;. </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">03</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">* </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">04</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">* @param username </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">05</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- </span>``<span style="font-size:12.0pt;color:#666666">用户名,注:使用用户全称,如:<span lang="EN-US">CN=SquallZhong/O=VGOLive Technology </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">06</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">* @param creationTime </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">07</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- </span>``<span style="font-size:12.0pt;color:#666666">创建时间 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">08</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">* @param durationMinutes </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">09</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- </span>``<span style="font-size:12.0pt;color:#666666">到期时间,单位:分钟 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">10@param ltpaSecretStr </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">11</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- Domino Ltpa </span>``<span style="font-size:12.0pt;color:#666666">加密字符串 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">12</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">* @return - </span>``<span style="font-size:12.0pt;color:#666666">返回已<span lang="EN-US">Base64</span>编码的<span lang="EN-US">Ltpa Cookie. </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">13</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">* @throws NoSuchAlgorithmException </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">14</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">* @throws Base64DecodeException </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">15</span>     <span lang="EN-US" style="font-size:12.0pt;color:#666666">*/</span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">16</span>    public static <span lang="EN-US" style="font-size:12.0pt;color:#666666">String createLtpaToken(String username, </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">17</span>            <span lang="EN-US" style="font-size:12.0pt;color:#666666">GregorianCalendar creationTime, </span>int <span lang="EN-US" style="font-size:12.0pt;color:#666666">durationMinutes, </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">18</span>            <span lang="EN-US" style="font-size:12.0pt;color:#666666">String ltpaSecretStr) </span>throws <span lang="EN-US" style="font-size:12.0pt;color:#666666">NoSuchAlgorithmException { </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">19</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// Base64</span>``<span style="font-size:12.0pt;color:#666666">解码<span lang="EN-US">ltpaSecretStr </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">20</span>        byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] ltpaSecret = Base64.decodeBase64(ltpaSecretStr.getBytes()); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">21</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">用户名字节数组 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">22</span>        byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] usernameArray = username.getBytes(); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">23</span>        byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] workingBuffer = </span>new byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[preUserDataLength </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">24</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">+ usernameArray.length + ltpaSecret.length]; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">25&nbsp;</span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">26</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">设置<span lang="EN-US">ltpaToken</span>版本至<span lang="EN-US">workingBuffer </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">27</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">System.arraycopy(ltpaTokenVersion, </span>0<span lang="EN-US" style="font-size:12.0pt; color:#666666">, workingBuffer, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">28</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">ltpaTokenVersion.length); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">29</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">获得过期时间,过期时间<span lang="EN-US">=</span>当前时间<span lang="EN-US">+</span>到期时间<span lang="EN-US">(</span>分钟<span lang="EN-US">) </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">30</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">GregorianCalendar expirationDate = (GregorianCalendar) creationTime </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">31</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">.clone(); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">32</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">expirationDate.add(Calendar.MINUTE, durationMinutes); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">33&nbsp;</span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">34</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">转换创建时间至<span lang="EN-US">16</span>进制字符串 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">35</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">String hex = dateStringFiller </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">36</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">+ Integer.toHexString( </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">37</span>                        <span lang="EN-US" style="font-size:12.0pt;color:#666666">(</span>int<span lang="EN-US" style="font-size:12.0pt;color:#666666">) (creationTime.getTimeInMillis() / </span>1000<span lang="EN-US" style="font-size:12.0pt;color:#666666">)) </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">38</span>                        <span lang="EN-US" style="font-size:12.0pt;color:#666666">.toUpperCase(); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">39</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">设置创建时间至<span lang="EN-US">workingBuffer </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">40</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">System.arraycopy(hex.getBytes(), hex.getBytes().length </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">41</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">- dateStringLength, workingBuffer, creationDatePosition, </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">42</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">dateStringLength); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">43&nbsp;</span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">44</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">转换过期时间至<span lang="EN-US">16</span>进制字符串 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">45</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">hex = dateStringFiller </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">46</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">+ Integer.toHexString( </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">47</span>                        <span lang="EN-US" style="font-size:12.0pt;color:#666666">(</span>int<span lang="EN-US" style="font-size:12.0pt;color:#666666">) (expirationDate.getTimeInMillis() / </span>1000<span lang="EN-US" style="font-size:12.0pt;color:#666666">)) </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">48</span>                        <span lang="EN-US" style="font-size:12.0pt;color:#666666">.toUpperCase(); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">49</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">设置过期时间至<span lang="EN-US">workingBuffer </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">50</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">System.arraycopy(hex.getBytes(), hex.getBytes().length </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">51</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">- dateStringLength, workingBuffer, expirationDatePosition, </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">52</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">dateStringLength); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">53&nbsp;</span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">54</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">设置用户全称至<span lang="EN-US">workingBuffer </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">55</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">System.arraycopy(usernameArray, </span>0<span lang="EN-US" style="font-size:12.0pt; color:#666666">, workingBuffer, preUserDataLength, </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">56</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">usernameArray.length); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">57&nbsp;</span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">58</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">设置已<span lang="EN-US">Base64</span>解码<span lang="EN-US">ltpaSecret</span>至<span lang="EN-US">workingBuffer </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">59</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">System.arraycopy(ltpaSecret, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, workingBuffer, preUserDataLength </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">60</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">+ usernameArray.length, ltpaSecret.length); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">61</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">创建<span lang="EN-US">Hash</span>字符串 </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">62</span>        byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] hash = createHash(workingBuffer); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">63&nbsp;</span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">64</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// ltpaToken</span>``<span style="font-size:12.0pt;color:#666666">版本<span lang="EN-US">+</span>开始时间<span lang="EN-US">(16</span>进制<span lang="EN-US">)+</span>到期时间<span lang="EN-US">(16</span>进制<span lang="EN-US">)+</span>用户全名<span lang="EN-US">+SHA-1(ltpaToken</span>版本<span lang="EN-US">+</span>开始时间<span lang="EN-US">(16</span>进制<span lang="EN-US">)+</span>到期时间<span lang="EN-US">(16</span>进制<span lang="EN-US">)+</span>用户全名<span lang="EN-US">) </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">65</span>        byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[] outputBuffer = </span>new byte<span lang="EN-US" style="font-size:12.0pt;color:#666666">[preUserDataLength + usernameArray.length </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">66</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">+ hashLength]; </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">67</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">System.arraycopy(workingBuffer, </span>0<span lang="EN-US" style="font-size:12.0pt; color:#666666">, outputBuffer, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, preUserDataLength </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">68</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">+ usernameArray.length); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">69</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">System.arraycopy(hash, </span>0<span lang="EN-US" style="font-size:12.0pt;color:#666666">, outputBuffer, preUserDataLength </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">70</span>                <span lang="EN-US" style="font-size:12.0pt;color:#666666">+ usernameArray.length, hashLength); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">71</span>        <span lang="EN-US" style="font-size:12.0pt;color:#666666">// </span>``<span style="font-size:12.0pt;color:#666666">返回已<span lang="EN-US">Base64</span>编码的<span lang="EN-US">outputBuffer </span></span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">72</span>        return new <span lang="EN-US" style="font-size:12.0pt;color:#666666">String(Base64.encodeBase64(outputBuffer)); </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">73</span>    <span lang="EN-US" style="font-size:12.0pt;color:#666666">} </span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666">74…...</span>

<span lang="EN-US" style="font-size: 12.0pt;color:#666666"> </span>

本文与同事在2013年设计一级部署系统架构时所定,同事曾经发表于百度文库




your support will encourage me to continue to create!
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)