考虑以下设置:
- 部署在 Websphere Application Server 上的 Web 应用程序(如果重要,则为 6.1)
- 该应用程序将通过 webseal 反向代理访问
- webseal 负责认证并传递一个 LTPA 令牌作为有效认证的标志
如果我没记错的话,LTPA 令牌包含用户名、角色等信息。
问题:如何从我的 java Web 应用程序中的 LTPA 令牌访问此信息?
考虑以下设置:
如果我没记错的话,LTPA 令牌包含用户名、角色等信息。
问题:如何从我的 java Web 应用程序中的 LTPA 令牌访问此信息?
查看 LTPA 令牌内部非常适合调试,我们经常使用它。您需要 ltpa-key 和密码才能正常工作
/* 版权声明 # 版权所有 (C) 2007,Cosmin Stejerean (http://www.offbytwo.com) # # 您可以根据知识共享署名许可的条款自由使用此代码 # 可在 http://creativecommons.org/licenses/by/3.0/ 获得 # 只要您包含以下通知“包括来自 Cosmin Stejerean (http://www.offbytwo.com) 的代码” */ 导入 java.security.Key; 导入 java.security.MessageDigest; 导入 java.security.spec.KeySpec; 导入java.sql.Date; 导入 java.text.SimpleDateFormat; 导入 java.util.Arrays; 导入 java.util.StringTokenizer; 导入 javax.crypto.Cipher; 导入 javax.crypto.SecretKeyFactory; 导入 javax.crypto.spec.DESedeKeySpec; 导入 sun.misc.BASE64Decoder; //共享的 3DES 密钥本身是使用 LTPA 密码的 SHA 哈希值加密的(用 0x0 填充,最多 24 个字节)。 公共类 LtpaDecoder { 私有字符串 ltpa3DESKey = "JvJRzwdhKk6o40FuATa9acKD2uaXswVHlUsn2c2+MKQ="; 私人字符串 ltpaPassword = "秘密密码"; 私人字符串 sUserInfo = ""; 私人日期到期; 私有字符串 sFullToken = ""; 私人字符串 sSignature = ""; 公共静态无效主要(字符串 [] 参数) { 字符串 tokenCipher = "vsof5exb990sb2r5hRJ+bneCnmBTuLQ3XF+......"; 尝试 { LtpaDecoder t = new LtpaDecoder(tokenCipher); System.out.println("用户信息:" + t.getUserInfo()); System.out.println("有效期:" + t.getExpiryDate()); System.out.println("完整令牌:" + t.getFullToken()); } 捕获(异常 e){ e.printStackTrace(); } } 公共 LtpaDecoder(String fulltoken) 抛出异常 { byte[] secretKey = getSecretKey(this.ltpa3DESKey, this.ltpaPassword); String ltpaPlaintext = new String(decryptLtpaToken(fulltoken, secretKey)); extractTokenData(ltpaPlaintext); } 私人无效extractTokenData(字符串令牌) { System.out.println("\n"); StringTokenizer st = new StringTokenizer(token, "%"); sUserInfo = st.nextToken(); 字符串 sExpires = st.nextToken(); sSignature = st.nextToken(); dExpiry = new Date(Long.parseLong(sExpires)); sFullToken = 令牌; } 公共字符串 getSignature() { 返回签名; } 公共字符串 getFullToken() { 返回 sFullToken; } 公共字符串 getUserInfo() { 返回 sUserInfo; } 公共字符串 getExpiryDate() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); 返回 sdf.format(dExpiry); } private byte[] getSecretKey(String shared3DES, String password) 抛出异常 { MessageDigest md = MessageDigest.getInstance("SHA"); md.update(password.getBytes()); 字节[] hash3DES = 新字节[24]; System.arraycopy(md.digest(), 0, hash3DES, 0, 20); Arrays.fill(hash3DES, 20, 24, (byte) 0); // 解密真正的密钥并返回 BASE64Decoder base64decoder = new BASE64Decoder(); 返回解密(base64decoder.decodeBuffer(shared3DES),hash3DES); } public byte[] decryptLtpaToken(String encryptedLtpaToken, byte[] key) 抛出异常 { BASE64Decoder base64decoder = new BASE64Decoder(); 最终字节[] ltpaByteArray = base64decoder.decodeBuffer(encryptedLtpaToken); 返回解密(ltpaByteArray,密钥); } 公共字节 [] 解密(字节 [] 密文,字节 [] 密钥)抛出异常 { final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); final KeySpec keySpec = new DESedeKeySpec(key); 最终密钥 secretKey = SecretKeyFactory.getInstance("TripleDES").generateSecret(keySpec); cipher.init(Cipher.DECRYPT_MODE,secretKey); 返回 cipher.doFinal(密文); } }
您不直接访问 LTPA 令牌,而是假设 WebSphere 已根据其身份验证过程为您建立了安全上下文。
然后你可以使用
getUserPrincipal()
在您的 HttpServletRequest 对象上访问用户的身份。
角色特定于当前资源(serlvet、ejb ...),因此您使用 HttpServletRequest 方法
isUserInRole()
确定用户是否在角色中。
你也可以使用方法
public static javax.security.auth.Subject getCallerSubject()
获取进一步的安全信息,包括组成员身份。