java - 来自 Java 的 kerberos - 为当前经过身份验证的用户获取主题

标签 java security kerberos

我们公司有一个 kerberos 域,我正在运行一些 Java/Kerberos examples .我的问题是从服务器的角度来看登录机制。在运行服务器示例 GssServer.java 时,我需要获取一个 javax.security.auth.Subject;在提供的代码中,这是通过 LoginContext 因此:

// Create a LoginContext with a callback handler and login
LoginContext context = new LoginContext(name, new TextCallbackHandler());
context.login();

Subject subject = context.getSubject();

一切正常,当我运行该示例时,我看到了一个可爱的登录提示。然而,我的问题是,这不是我的服务器真正运行的方式,也不是我被引导去理解我应该如何从 kerberos 域中提供服务的方式。在 GssServer 示例中,问题是我的服务器(读取:服务)应该不需要验证自己KDC 以呈现其为客户服务。访问服务器端 keytab 文件应该足以执行此操作。因此对于示例配置:

//jaas-krb5.conf
server {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    keyTab="/home/myusr/my-server.keytab"
    principal="myserv/mymachine.some.domain";
};

在 Java 代码中:

GSSManager manager = GSSManager.getInstance();
Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
GSSName gssName = manager.createName("myserv/mymachine.some.domain@THE.REALM.COM", 
                                     GSSName.NT_HOSTBASED_SERVICE);
GSSCredential serverCreds = manager.createCredential(gssName,
                                     GSSCredential.DEFAULT_LIFETIME,
                                     krb5Mechanism,
                                     GSSCredential.ACCEPT_ONLY);

问题在于 jaas-krb5.conf 文件中的server 信息不可用除非我通过行:

Jaas.loginAndAction("server", action);     

我不应该通过这个认证!但是,如果我不对自己进行身份验证,我最终会得到:

Exception in thread "main" GSSException: No valid credentials provided (Mechanism level: Attempt to obtain new ACCEPT credentials failed!)
    at sun.security.jgss.krb5.Krb5AcceptCredential.getKeysFromSubject(Krb5AcceptCredential.java:188)
    at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.java:73)
    at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:77)
    at sun.security.jgss.GSSManagerImpl.getCredentialElement(GSSManagerImpl.java:149)
    at sun.security.jgss.GSSCredentialImpl.add(GSSCredentialImpl.java:389)
    at sun.security.jgss.GSSCredentialImpl.<init>(GSSCredentialImpl.java:45)
    at sun.security.jgss.GSSManagerImpl.createCredential(GSSManagerImpl.java:102)
    at gsa.hk.GssServer$GssServerAction.run(GssServer.java:79)
    at gsa.hk.GssServer.main(GssServer.java:57)
Caused by: javax.security.auth.login.LoginException: No LoginModules configured for com.sun.security.jgss.accept
    at javax.security.auth.login.LoginContext.init(LoginContext.java:256)
    at javax.security.auth.login.LoginContext.<init>(LoginContext.java:403)
    at sun.security.jgss.LoginUtility.login(LoginUtility.java:72)
    at sun.security.jgss.krb5.Krb5Util.getKeysFromSubject(Krb5Util.java:205)
    at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:184)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.security.jgss.krb5.Krb5AcceptCredential.getKeysFromSubject(Krb5AcceptCredential.java:181)
    ... 8 more

出现问题也就不足为奇了。毕竟,除非我掌握了 server 主题,否则我怎么知道我的 keytab 在哪里,或者我正在提供什么服务?

所以我的问题是:如何在不在代码中验证自己的情况下告诉 GSS API 有关 key 表/服务的信息?

最佳答案

好的。因此,假设您知道可以使用 keytab 文件代替身份验证,这将变得非常容易JavaDoc for Krb5LoginModule 中对此进行了概述。

基本上,如果我

loginAndAction("anything", action)

那么我的配置应该是这样的:

//jaas-krb5.conf
anything {
    com.sun.security.auth.module.Krb5LoginModule required
    useKeyTab=true
    storeKey=true
    doNotPrompt=true
    keyTab="/home/myusr/my-server.keytab"
    principal="myserv/mymachine.some.domain";
};

重要的一点是添加了 doNotPrompt=true。设置此属性后,服务器代码使用 key 表中的信息

关于java - 来自 Java 的 kerberos - 为当前经过身份验证的用户获取主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/979910/

相关文章:

php - 在数据库中加密密码有什么意义?

c - 为什么这个程序永远不会以标志 `-O3` 终止?

java - 如何信任我的自签名证书

java - 如何为 Tomcat 设置透明的 kerberos 身份验证?

java - StringUtils.isBlank() 与 String.isEmpty()

Java Restful web服务方法消费MultiPart数据抛异常

java - Volley 请求队列返回 null

c++ - 在 Linux 上使用 C++ 对 Active Directory 进行身份验证

redis - 从 redis 服务器进程中运行 shell 命令

java - 使用 Java (netbeans) 连接到远程 SQL 服务器时出现 SSL 错误