当前位置: 首页 > 知识库问答 >
问题:

JAASKerberos身份验证对于具有国际字符的用户失败

费学
2023-03-14

下面是我用于尝试Active Directory身份验证的Kerberos JAAS客户端示例(基于此Spring源代码http://goo.gl/qRFNKY).

当名称和密码仅包含英文字符时,我可以对用户进行身份验证。

//works
client.login("joe@MYDOMAIN.COM", "Password1");

当任一字段包含国际字符时,它将失败。

//fails
client.login("áá@MYDOMAIN.COM", "çã123");

如何将这段代码国际化?

package aa;

import java.io.IOException;
import java.util.HashMap;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;


public class SampleKerberosClient {

    public static void main(String[] args) throws LoginException {
        SampleKerberosClient client = new SampleKerberosClient();

        //works
            client.login("joe@MYDOMAIN.COM", "Password1");

        //fails
            client.login("áá@MYDOMAIN.COM", "çã123");

    }

    private boolean debug = true;
    private String krbConfLocation = "/Users/aa/java/jaas/src/aa/krb5.conf";

    public SampleKerberosClient() {
        System.setProperty("java.security.krb5.conf", krbConfLocation);
        System.setProperty("sun.security.krb5.debug", "true");
    }

    public String login(String username, String password) throws LoginException {
        System.out.println("Trying to authenticate " + username + " with Kerberos");
        String validatedUsername;

        LoginContext loginContext = new LoginContext("", null, new KerberosClientCallbackHandler(username, password),
                new LoginConfig(this.debug));
        loginContext.login();
        System.out.println("Kerberos authenticated user: " + loginContext.getSubject());
        validatedUsername = loginContext.getSubject().getPrincipals().iterator().next().toString();
        loginContext.logout();

        System.out.println("validated user name: " + validatedUsername);
        return validatedUsername;

    }


    private static class LoginConfig extends Configuration {
        private boolean debug;

        public LoginConfig(boolean debug) {
            super();
            this.debug = debug;
        }

        @Override
        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
            HashMap<String, String> options = new HashMap<String, String>();
            options.put("storeKey", "true");
            if (debug) {
                options.put("debug", "true");
            }

            return new AppConfigurationEntry[]{new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options),};
        }
    }

    private static class KerberosClientCallbackHandler implements CallbackHandler {
        private String username;
        private String password;

        public KerberosClientCallbackHandler(String username, String password) {
            this.username = username;
            this.password = password;
        }

        @Override
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            for (Callback callback : callbacks) {
                if (callback instanceof NameCallback) {
                    NameCallback ncb = (NameCallback) callback;
                    ncb.setName(username);
                } else if (callback instanceof PasswordCallback) {
                    PasswordCallback pwcb = (PasswordCallback) callback;
                    pwcb.setPassword(password.toCharArray());
                } else {
                    throw new UnsupportedCallbackException(callback, "We got a " + callback.getClass().getCanonicalName()
                            + ", but only NameCallback and PasswordCallback is supported");
                }
            }
        }
    }
}

下面是控制台输出(失败时)

Trying to authenticate áá@MYDOMAIN.COM with Kerberos
Debug is  true storeKey true useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is null tryFirstPass is false useFirstPass is false storePass is false clearPass is false
        [Krb5LoginModule] user entered username: áá@MYDOMAIN.COM

Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 3 1 23 16 17 18.
Acquire TGT using AS Exchange
>>> KdcAccessibility: reset
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 3 1 23 16 17 18.
>>> KrbAsReq calling createMessage
>>> KrbAsReq in createMessage
>>> KrbKdcReq send: kdc=ADSERVER.MYDOMAIN.COM.com UDP:88, timeout=30000, number of retries =3, #bytes=179
>>> KDCCommunication: kdc=ADSERVER.MYDOMAIN.COM UDP:88, timeout=30000,Attempt =1, #bytes=179
>>> KrbKdcReq send: #bytes read=116
>>> KrbKdcReq send: #bytes read=116
>>> KdcAccessibility: remove ADSERVER.MYDOMAIN.COM.
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
     sTime is Mon Mar 31 17:10:03 PDT 2014 1396311003000
     suSec is 268438
     error code is 6
     error Message is Client not found in Kerberos database
     realm is MYDOMAIN.COM
     sname is krbtgt/MYDOMAIN.COM
     msgType is 30
        [Krb5LoginModule] authentication failed 
Client not found in Kerberos database (6)
Exception in thread "main" javax.security.auth.login.LoginException: Client not found in Kerberos database (6)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:696)
    at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
    at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
    at javax.security.auth.login.LoginContext$5.run(LoginContext.java:706)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokeCreatorPriv(LoginContext.java:703)
    at javax.security.auth.login.LoginContext.login(LoginContext.java:575)
    at aa.SampleKerberosClient.login(SampleKerberosClient.java:45)
    at aa.SampleKerberosClient.main(SampleKerberosClient.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: KrbException: Client not found in Kerberos database (6)
    at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:66)
    at sun.security.krb5.KrbAsReq.getReply(KrbAsReq.java:446)
    at sun.security.krb5.Credentials.sendASRequest(Credentials.java:419)
    at sun.security.krb5.Credentials.acquireTGT(Credentials.java:368)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:662)
    ... 18 more
Caused by: KrbException: Identifier doesn't match expected value (906)
    at sun.security.krb5.internal.KDCRep.init(KDCRep.java:133)
    at sun.security.krb5.internal.ASRep.init(ASRep.java:58)
    at sun.security.krb5.internal.ASRep.<init>(ASRep.java:53)
    at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:50)
    ... 22 more

共有1个答案

韦睿
2023-03-14

我之前已经回答过类似的问题,搜索爱尔兰法达和科贝罗斯。KerberosLoginModule 显然不能正确地将字符转换为字节。它应该生成一个 UTF-8 字节序列。您应该使用Wireshark检查流量。

 类似资料:
  • 我有一个API在Apache堆栈上运行,使用Java。我继承了一个遗留代码库,需要找到这个错误来自哪里显然是上一个开发人员构建了一个不能工作的特性,这就是错误所在,但没有更多信息。它使用Drupal webservice模块,发送调用的代码如下所示 我可以从哪里开始寻找这个错误,或者它可能意味着什么,你有什么想法吗? 完整的堆栈跟踪如下所示::: 用户失败:null。java.lang.Unsup

  • 因此,我在Centos 8和postgresql-12上遇到了身份验证问题。添加服务器期间出现以下错误:::pgadmin4错误创建服务器 本地主机上的连接:postgres连接本地主机 我真的尝试了很多答案,但没有一个对我有用。pg_nba.conf文件现在有以下字符串: 本地所有信任 本地所有md5 托管所有127.0.0.1/32 md5 主机所有::1/128 md5 托管所有10.1.1

  • 我第一次将应用程序部署到数字海洋,遇到了两个(可能更多)问题。 1) 在将添加到Gemfile后,我无法。我发现kgio与windows不兼容。我必须要Gemfile吗。当我通过capistrano部署时是否存在锁?我如何解决这个问题? 2)我在服务器上的postgreql上遇到身份验证问题。 我运行了这些命令(以及其他一些命令): 每次我限制部署时,我都会收到这个错误: 我尝试输入一个我知道不存

  • 当我创建一个新用户,但它无法登录数据库时。 我这样做: 然后创建一个数据库: 之后,我尝试登录,但出现错误: 我试图解决这个问题,但失败了。

  • 问题内容: 我一直在玩漂亮的汤和解析网页几天。在编写的所有脚本中,我一直使用一行代码作为救星。代码行是: 但是… 我想对(OPEN A URL WITH AUTHENTICATION)做同样的事情: 我无法打开网址并阅读需要身份验证的网页。我如何实现这样的目标: 问题答案: 看看官方文档中的如何使用urllib软件包获取Internet资源:

  • 问题内容: 我有一台服务器,使用Java应用程序处理数据库和文件。当我启动我的应用程序时,我使用以下命令提供有关文件访问服务器的报告: 每次启动我的应用程序(重新启动计算机后),即使服务器已打开,我也会得到错误的响应。原因是因为我必须提供另一个用户的身份验证。我要做的是通过要求我输入用户名/密码的Windows访问服务器,然后我得到了有关对服务器文件访问的真实响应。 有没有办法 通过Java 而不