使用 Spnego 解密 kerberos 票证

2022-09-03 18:32:28

我正在使用spnego(http://spnego.sourceforge.net)在JBoss下进行kerberos身份验证。

我需要解密 kerberos 票证才能访问将包含 PAC 数据的授权数据。需要 PAC 数据来决定向用户授予哪些角色。

如何访问和解密 kerberos 票证?我已经在网上搜索了例子,但毫不费力。


答案 1

这些家伙有一个完整的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 票证,你需要跳过一些箍。不知道你是否需要它。

授予


答案 2

我已经成功地将 http://spnego.sourceforge.net 的servlet过滤器与 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

希望这对任何人都有帮助。

__
马赛尔


推荐