考虑以下设置:
- 部署在 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()
获取进一步的安全信息,包括组成员身份。