14

JBoss での kerberos 認証にspnego ( http://spnego.sourceforge.net ) を使用しています。

PAC データを含む認証データにアクセスするには、Kerberos チケットを復号化する必要があります。ユーザーに付与するロールを決定するには、PAC データが必要です。

kerberos チケットにアクセスして解読する方法は? ネットで例を検索しましたが、努力はしませんでした。

4

5 に答える 5

8

これらの人は、完全な PAC デコードの実装を持っています。

http://jaaslounge.sourceforge.net/

次のようにトークン パーサーを使用できます。

HttpServletRequest request = (HttpServletRequest) req;
String header = request.getHeader("Authorization");
byte[] base64Token = header.substring(10).getBytes("UTF-8");
byte[] spnegoHeader = Base64.decode(base64Token);

SpnegoInitToken spnegoToken = new SpnegoInitToken(spnegoHeader);

基になる Kerberos チケットを解読したい場合は、いくつかのフープをジャンプする必要があります。それが必要かどうかわかりません。

許す

于 2011-01-07T18:26:32.983 に答える
8

http://spnego.sourceforge.netのサーブレット フィルターをhttp://jaaslounge.sourceforge.net/の PAC パーサーと組み合わせて使用​​することに成功しました。DER/ASN.1 パーサーで明示的に何かを行う必要はありません。

/** 
 * Retrieve LogonInfo (for example, Group SID) from the PAC Authorization Data
 * from a Kerberos Ticket that was issued by Active Directory.
 */  
byte[] kerberosTokenData = gssapiData;
try {
    SpnegoToken token = SpnegoToken.parse(gssapiData);
    kerberosTokenData = token.getMechanismToken();
} catch (DecodingException dex) {
    // Chromium bug: sends a Kerberos response instead of an spnego response 
    // with a Kerberos mechanism
} catch (Exception ex) {
    log.error("", ex);
}   

try {
    Object[] keyObjs = IteratorUtils.toArray(loginContext.getSubject()
                         .getPrivateCredentials(KerberosKey.class).iterator());
    KerberosKey[] keys = new KerberosKey[keyObjs.length];
    System.arraycopy(keyObjs, 0, keys, 0, keyObjs.length);

    KerberosToken token = new KerberosToken(kerberosTokenData, keys);
    log.info("Authorizations: "); 
    for (KerberosAuthData authData : token.getTicket().getEncData()
                                             .getUserAuthorizations()) {
        if (authData instanceof KerberosPacAuthData) {
            PacSid[] groupSIDs = ((KerberosPacAuthData) authData)
                                      .getPac().getLogonInfo().getGroupSids();
            log.info("GroupSids: " + Arrays.toString(groupSIDs));
            response.getWriter().println("Found group SIDs: " + 
                Arrays.toString(groupSIDs));
        } else {
            log.info("AuthData without PAC: " + authData.toString());
        }   
    }   
} catch (Exception ex) {
    log.error("", ex);
}   

また、新しい HttpFilter (spnego.sf.net からフォーク) を作成しました: spnego-pac は、getUserPrincipal() を介して LogonInfo を公開します。

上記のコードを完全に示すサンプル プロジェクトは、次の場所にあります。

https://github.com/EleotleCram/jetty-spnego-demo

spnego-pac フィルター (上記の例で使用) は次の場所にあります。

https://github.com/EleotleCram/spnego.sf.net-fork

これが誰にとっても役立つことを願っています。

__
マルセル

于 2012-04-10T15:22:14.413 に答える
5

次のようなメカニズムトークンを取得する場合spnegoToken

byte[] mechanismToken = spnegoToken.getMechanismToken(); 

メカニズムトークンは通常KerberosApRequestです。KerberosTokenをとるコンストラクターがありますKerberosApRequestmechanismTokenキーと一緒にバイト配列を渡すだけで、コンテンツを復号化できます。

于 2011-01-17T22:40:25.050 に答える
5

私は問題に対する独自の解決策を提供します:

BouncyCastle ライブラリ (トークンの一部を解析するため) と JaasLounge (トークンの暗号化された部分を解読するため) に基づいてソリューションを作成しました。残念ながら、JaasLounge から spnego トークン全体をデコードするコードは、私の要件では失敗しました。私はそれを自分で書かなければなりませんでした。

最初に byte[] 配列から DERObjects を構築して、チケットを部分的にデコードしました。

private DERObject[] readDERObjects(byte[] bytes) throws IOException {
    ASN1InputStream stream = new ASN1InputStream(new ByteArrayInputStream(
        bytes));
    List<DERObject> objects = new ArrayList<DERObject>();
    DERObject curObj;
    while ((curObj = stream.readObject()) != null) {
        objects.add(untag(curObj));
    }
    return objects.toArray(new DERObject[0]);
}

untag() は私のヘルパー関数で、DERTaggedObject のラッピングを削除します

private DERObject untag(DERObject src) {
    if (src instanceof DERTaggedObject) {
        return ((DERTaggedObject) src).getObject();
    }
    return src;
}

特定の DERObject から DERObject のシーケンスを抽出するために、別のヘルパー関数を作成しました。

private DERObject[] readDERObjects(DERObject container) throws IOException {
// do operation varying from the type of container
if (container instanceof DERSequence) {
    // decode using enumerator
    List<DERObject> objects = new ArrayList<DERObject>();
    DERSequence seq = (DERSequence) container;
    Enumeration enumer = seq.getObjects();
    while (enumer.hasMoreElements()) {
    DERObject curObj = (DERObject) enumer.nextElement();
    objects.add(untag(curObj));
    }
    return objects.toArray(new DERObject[0]);
}
if (container instanceof DERApplicationSpecific) {
    DERApplicationSpecific aps = (DERApplicationSpecific) container;
    byte[] bytes = aps.getContents();
    return readDERObjects(bytes);
}
if (container instanceof DEROctetString) {
    DEROctetString octets = (DEROctetString) container;
    byte[] bytes = octets.getOctets();
    return readDERObjects(bytes);
}
throw new IllegalArgumentException("Unable to decode sequence from "+container);
}

最後に、暗号化された部分を含む DEROCtetStream を取得したら、KerberosEncData を使用しました。

KerberosEncData encData = new KerberosEncData(decrypted, matchingKey);

クライアント ブラウザから受信したバイト シーケンスは、チケット ルート - レベル 0 である単一の DERApplicationSpecific に解析されます
。ルートには以下が含まれます。

  • DERObjectIdentifier - SPNEGO OID
  • DERSequence - レベル 1

レベル 1 には以下が含まれます。

  • DERObjectIdentifier の SEQUENCE - メカ タイプ
  • DEROctetString - ラップされた DERApplicationSepecific - レベル 2

レベル 2 には以下が含まれます。

  • DERObjectIndentifier - Kerberos OID
  • KRB5_AP_REQ タグ0x01 0x00、ブール値として解析 (false)
  • DERApplicationSpecific - DERSequence のコンテナー - レベル 3

レベル 3 には以下が含まれます。

  • バージョン番号 - 5 である必要があります
  • メッセージタイプ - 14 (AP_REQ)
  • AP オプション (DERBITString)
  • DERApplicationSpecific - チケット部分でラップされた DERSequence
  • チケット部分が追加された DERSequence - 未処理

チケット部分 - レベル 4 には以下が含まれます。

  • チケットのバージョン - 5 である必要があります
  • チケットレルム - ユーザーが認証されるレルムの名前
  • サーバー名のDERSequence。各サーバー名は、サーバー名とインスタンス名の 2 つの文字列の DERSequence です。
  • 部分暗号化されたDERSequence

暗号化された部分シーケンス (レベル 5) には以下が含まれます。

  • 使用アルゴリズム番号
    • 1、3 - DES
    • 16 - des3-cbc-sha1-kd
    • 17 - ETYPE-AES128-CTS-HMAC-SHA1-96
    • 18 - ETYPE-AES256-CTS-HMAC-SHA1-96
    • 23 - RC4-HMAC
    • 24 - RC4-HMAC-EXP
  • 鍵のバージョン番号
  • 暗号化部分 (DEROctetStream)

問題は、シーケンス 0x01 0x00 が見つかったときに ArrayIndexOutOfBoundException をスローする DERBoolean コンストラクターにありました。そのコンストラクターを変更する必要がありました:

public DERBoolean(
    byte[]       value)
{
// 2011-01-24 llech make it byte[0] proof, sequence 01 00 is KRB5_AP_REQ
if (value.length == 0)
    this.value = 0;
else
    this.value = value[0];
}
于 2013-08-23T16:26:32.730 に答える
2

spnego を使用してからしばらく経ちます (ほぼ 1 年) ... とてもクールな質問ですね。

私は少し掘り下げて、MS-ADで動作していたが、今日はそれを感じていない、しばらく前に持っていたコードを実行しようとしていました:-/

とにかく、Google でこのリンクを見つけました: http://www.google.com/url?sa=t&source=web&cd=1&sqi=2&ved=0CBMQFjAA&url=http%3A%2F%2Fbofriis.dk%2Ffiles%2Fms_kerberos_pac.pdf&rct=j&q =java%20kerberos%20privilege%20attribute%20certificate&ei=2FASTbaLGcP38Abk07iQDg&usg=AFQjCNHcIfQRUTxkQUvLRcgOaQksCALTHA&sig2=g8yn7ie1PbzSkE2Mfv41Bw&cad=rja

うまくいけば、それはあなたにいくつかの洞察を与えることができます.

于 2010-12-22T19:31:16.787 に答える