Как использовать информацию в токене LTPA - PullRequest
5 голосов
/ 22 октября 2009

Рассмотрим следующую настройку:

  • Веб-приложение, развернутое на сервере приложений Websphere (6.1, если это имеет значение)
  • приложение будет доступно через обратный прокси-сервер веб-печати
  • веб-печать заботится об аутентификации и передает маркер LTPA как признак действительной аутентификации

Если я правильно понял, токен LTPA содержит такую ​​информацию, как имя пользователя, роли и т. Д.

Вопрос: как мне получить доступ к этой информации из токена LTPA в моем веб-приложении java?

Ответы [ 2 ]

10 голосов
/ 22 октября 2009

Просмотр токенов LTPA отлично подходит для отладки, мы используем это много. Вам понадобится ключ ltpa и пароль, чтобы это работало

/* 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);
    }
}
9 голосов
/ 22 октября 2009

У вас нет прямого доступа к токену LTPA, скорее вы предполагаете, что WebSphere установил для вас контекст безопасности на основе своих процедур аутентификации.

Вы можете использовать

getUserPrincipal()

в вашем объекте HttpServletRequest для доступа к личности пользователя.

Роли относятся к текущему ресурсу (serlvet, ejb ...) и, следовательно, вы используете метод HttpServletRequest

isUserInRole()

, чтобы определить, находится ли пользователь в роли.

Вы также можете использовать метод

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

для получения дополнительной информации о безопасности, включая членство в группах.

...