2009-10-22 51 views
5

考虑以下设置:如何使用信息的LTPA令牌

  • 部署在WebSphere Application Server上(6.1,如果它很重要)web应用
  • 应用程序将打通一个访问的WebSEAL反向代理
  • 在WebSEAL需要认证的关怀和传递LTPA令牌作为有效的身份验证

的迹象。如果我这样做是正确的LTPA令牌包含用户名一样,ROL信息es等等。

问题:我如何从我的java web应用程序中的LTPA令牌访问这些信息?

回答

9

您不直接访问LTPA令牌,而是假定WebSphere已根据其身份验证过程为您建立了安全上下文。

然后可以使用

getUserPrincipal() 

您HttpServletRequest对象上访问该用户的身份。

角色,尤其适用于当前资源(的serlvet,EJB ...),因此您使用HttpServletRequest的方法

isUserInRole() 

,以确定用户是否是一个角色。

您也可以使用该方法

public static javax.security.auth.Subject getCallerSubject() 

获得进一步的安全信息,包括组成员。

+0

太棒了,正是我一直在寻找的东西。 Thanx – 2009-10-23 15:42:52

10

寻找LTPA令牌很适合调试,我们使用这个很多。您需要使用ltpa-key和密码才能正常工作

 
/* Copyright notice 
# Copyright (C) 2007, Cosmin Stejerean (http://www.offbytwo.com) 
# 
# You are free to use this code under the terms of the Creative Commons Attribution license 
# available at http://creativecommons.org/licenses/by/3.0/ 
# so long as you include the following notice 'includes code from Cosmin Stejerean (http://www.offbytwo.com)' 
*/ 

import java.security.Key; 
import java.security.MessageDigest; 
import java.security.spec.KeySpec; 
import java.sql.Date; 
import java.text.SimpleDateFormat; 
import java.util.Arrays; 
import java.util.StringTokenizer; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.DESedeKeySpec; 

import sun.misc.BASE64Decoder; 


//The shared 3DES key is itself encrypted using the SHA hash value of the LTPA password (padded with 0x0 upto 24 bytes). 

public class LtpaDecoder 
{ 
    private String ltpa3DESKey = "JvJRzwdhKk6o40FuATa9acKD2uaXswVHlUsn2c2+MKQ="; 
    private String ltpaPassword = "secretpassword"; 

    private String sUserInfo = ""; 
    private Date dExpiry; 
    private String sFullToken = ""; 
    private String sSignature = ""; 

    public static void main(String[] args) 
    { 
      String tokenCipher = "vsof5exb990sb2r5hRJ+bneCnmBTuLQ3XF+......"; 

      try { 
      LtpaDecoder t = new LtpaDecoder(tokenCipher); 
      System.out.println("UserInfo: " + t.getUserInfo()); 
      System.out.println("Expiry: " + t.getExpiryDate()); 
      System.out.println("Full token: " + t.getFullToken()); 
     } 
     catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public LtpaDecoder(String fulltoken) throws Exception { 
     byte[] secretKey = getSecretKey(this.ltpa3DESKey, this.ltpaPassword); 
     String ltpaPlaintext = new String(decryptLtpaToken(fulltoken, secretKey)); 

     extractTokenData(ltpaPlaintext); 
    } 

    private void extractTokenData(String token) 
    { 
     System.out.println("\n"); 
     StringTokenizer st = new StringTokenizer(token, "%"); 

     sUserInfo = st.nextToken(); 
     String sExpires = st.nextToken(); 
     sSignature = st.nextToken(); 
     dExpiry = new Date(Long.parseLong(sExpires)); 
     sFullToken = token; 
    } 

    public String getSignature() { 
     return sSignature; 
    } 

    public String getFullToken() { 
     return sFullToken; 
    } 

    public String getUserInfo() { 
     return sUserInfo; 
    } 

    public String getExpiryDate() { 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); 
     return sdf.format(dExpiry); 
    } 

    private byte[] getSecretKey(String shared3DES, String password) throws Exception 
    { 
     MessageDigest md = MessageDigest.getInstance("SHA"); 
     md.update(password.getBytes()); 
     byte[] hash3DES = new byte[24]; 
     System.arraycopy(md.digest(), 0, hash3DES, 0, 20); 
     Arrays.fill(hash3DES, 20, 24, (byte) 0); 
     // decrypt the real key and return it 
     BASE64Decoder base64decoder = new BASE64Decoder(); 
     return decrypt(base64decoder.decodeBuffer(shared3DES), hash3DES); 
    } 

    public byte[] decryptLtpaToken(String encryptedLtpaToken, byte[] key) throws Exception 
    { 
     BASE64Decoder base64decoder = new BASE64Decoder(); 
     final byte[] ltpaByteArray = base64decoder.decodeBuffer(encryptedLtpaToken); 
     return decrypt(ltpaByteArray, key); 
    } 

    public byte[] decrypt(byte[] ciphertext, byte[] key) throws Exception { 
     final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); 
     final KeySpec keySpec = new DESedeKeySpec(key); 
     final Key secretKey = SecretKeyFactory.getInstance("TripleDES").generateSecret(keySpec); 

     cipher.init(Cipher.DECRYPT_MODE, secretKey); 
     return cipher.doFinal(ciphertext); 
    } 
} 
+0

冒着显而易见的风险,在开发环境中进行调试可能会很好,但我们并未将此技术的产品应用程序代码编译为基础,对吧? – djna 2009-10-22 20:08:37

+0

与IBM产品合作多年后,我会说这段代码在各种环境中都派上用场;) – Tommy 2009-10-22 21:58:20

+0

虽然我希望不需要在生产代码中使用这些东西(或者在那里找到它),但它仍然有用。 – 2009-10-23 15:44:23