2009-10-22 10 views
5

Si consideri la seguente configurazione: procuraCome utilizzare le informazioni in un LTPA gettone

  • Un webapplication distribuito su un WebSphere Application Server (6.1 se è importante)
  • l'applicazione otterrà accede tramite una WebSEAL inversa
  • il webseal si occupa dell'autenticazione e passa su un token LTPA come segno di autenticazione valido

Se ho capito bene, il token LTPA contiene informazioni come username, rol es e così via.

Domanda: come accedere a queste informazioni dal token LTPA nella mia applicazione web java?

risposta

9

Non si accede direttamente al token LTPA, ma si presume che WebSphere abbia stabilito un contesto di sicurezza per l'utente in base alle sue procedure di autenticazione.

È quindi possibile utilizzare

getUserPrincipal() 

sul HttpServletRequest oggetto per accedere l'identità dell'utente.

ruoli sono particolari alla risorsa corrente (serlvet, EJB ...) e quindi si utilizza il metodo HttpServletRequest

isUserInRole() 

per determinare se un utente è in un ruolo.

È inoltre possibile utilizzare il metodo

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

per ottenere ulteriori informazioni di sicurezza tra cui l'appartenenza al gruppo.

+0

Grande, esattamente quello che stavo cercando. Grazie –

10

Guardare dentro i token LTPA è ottimo per il debug, usiamo questo molto. Avrai bisogno della chiave ltpa e della password per farlo funzionare

 
/* 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

A rischio di affermare l'ovvio, pensare potrebbe essere utile per eseguire il debug in un ambiente di sviluppo, ma non basiamo il codice dell'applicazione di produzione su questa tecnica, giusto? – djna

+0

Dopo aver lavorato con prodotti IBM per alcuni anni, direi che questo codice è utile in tutti i tipi di ambienti;) – Tommy

+0

Anche se spero di non dover mai usare questo tipo di codice di produzione (o trovarlo lì), è comunque utile. –

Problemi correlati