使用Kerberos连接SMB共享时出现KrbException“消息流修改(41)”。

13

我在使用JCifs(Kerberos扩展版本1.3.17)进行文件管理时遇到了一些Kerberos身份验证问题。

这是我的krb5.conf的当前配置:

[libdefaults]
    default_realm = <REALM_NAME_UPPERCASE>
    udp_preference_limit = 1
[realms]
    <REALM_NAME_UPPERCASE> = {
        kdc = <DOMAIN_NAME_UPPERCASE>:88
        admin_server = <DOMAIN_NAME_UPPERCASE>
        default_domain = <DOMAIN_NAME_UPPERCASE>
    }
[domain_realm]
    .<domain_name> = <REALM_NAME_UPPERCASE>
    <domain_name> = <REALM_NAME_UPPERCASE>
[appdefaults]
    kinit = {
        renewable = true
        forwardable = true
    }

这是用于验证用户身份,然后尝试在网络文件服务器中查找文件的代码:

public static void main (String[] args) throws Exception {
    Subject subject = new Subject();
    System.setProperty("java.security.krb5.conf", "C:/krb5.conf");
    System.setProperty("sun.security.krb5.debug", "true");

    Map<String, Object> state = new HashMap<String, Object>();
    state.put("javax.security.auth.login.name", "USERNAME");
    state.put("javax.security.auth.login.password", "PASSWORD".toCharArray());

    Map<String, Object> options = new HashMap<String, Object>();
    options.put("debug", "true");
    options.put("useFirstPass", "true");

    Krb5LoginModule login = new Krb5LoginModule();
    login.initialize(subject, null, state, options);

    if (login.login()) {
        login.commit();
    }

    String path = "file://HOST/242269/"; // existing file server folder
    Kerb5Authenticator kerberosAuthenticator = new Kerb5Authenticator(subject);

    SmbFile smbFile = new SmbFile(path, kerberosAuthenticator);
    SmbFile[] files = smbFile.listFiles();

    for (SmbFile file : files) {
        System.out.println(file);
    }
}

现在,当我运行这段代码时,它说可以使用这些凭据对用户进行身份验证(当我更改凭据时,身份验证失败),并为此用户创建了一个票证。 之后,当我尝试通过CIFS检索文件目录的内容时,它会给出以下错误:

GSSException: No valid credentials provided (Mechanism level: Message stream modified (41))
at sun.security.jgss.krb5.Krb5Context.initSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
at jcifs.smb.SpnegoContext.initSecContext(SpnegoContext.java:80)
at jcifs.smb.Kerb5Authenticator.setup(Kerb5Authenticator.java:196)
at jcifs.smb.Kerb5Authenticator.access$000(Kerb5Authenticator.java:30)
at jcifs.smb.Kerb5Authenticator$1.run(Kerb5Authenticator.java:168)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Unknown Source)
at jcifs.smb.Kerb5Authenticator.sessionSetup(Kerb5Authenticator.java:166)
at jcifs.smb.SmbSession.sessionSetup(SmbSession.java:320)
at jcifs.smb.SmbSession.send(SmbSession.java:239)
at jcifs.smb.SmbTree.treeConnect(SmbTree.java:176)
at jcifs.smb.SmbFile.doConnect(SmbFile.java:925)
at jcifs.smb.SmbFile.connect(SmbFile.java:974)
at jcifs.smb.SmbFile.connect0(SmbFile.java:890)
at jcifs.smb.SmbFile.resolveDfs(SmbFile.java:669)
at jcifs.smb.SmbFile.send(SmbFile.java:783)
at jcifs.smb.SmbFile.doFindFirstNext(SmbFile.java:2009)
at jcifs.smb.SmbFile.doEnum(SmbFile.java:1758)
at jcifs.smb.SmbFile.listFiles(SmbFile.java:1735)
at jcifs.smb.SmbFile.listFiles(SmbFile.java:1668)

你可以在这里找到完整的错误日志(一些细节已被模糊化)

请问有人能指导我正确的方向,告诉我我在这里做错了什么吗?


另一个(有用的?)评论:此用户帐户无法访问文件服务器的根目录,仅限于该特定子文件夹。我不知道这是否相关。 - Dieter Hubau
尝试将您的 krb5.conf 和 login.conf 文件放置在 Tomcat 的 lib 文件夹中,然后再次尝试。 - vel
3个回答

17

8
请问您能否更具体地回答问题,并解释一下(最好附上代码),您的建议如何帮助提问者?请进一步说明一下。作为读者,我很难理解您的回答是如何解决问题的。在我看来,将链接发布为评论更合适。 - kkuilla
问题在于Kerberos通过基于密码和参数计算校验和来检查答案的完整性。如果接收到的答案是肯定的,但输入参数不匹配,则会出现“流修改”错误。最有可能的原因是服务器使用真实的大写流,而客户端使用小写流。 - eckes
这种一般性错误在某些环境下确实可能是由此引起的。虽然我不知道具体原因。 - user437212

16

很抱歉要顶一下,但我在Docker容器内启动Spark和Zeppelin时遇到了相同的问题,主节点是一个远程启用Kerberos的YARN集群。然而,在这种情况下,域名的大小写不是问题。

几个小时后,我找到了这个帖子,它建议从krb5.conf文件中删除以下行:

renew_lifetime = 7d

问题已解决,希望这能帮助到某些人。


2
删除那行代码后,对我也起作用了。 - Sudhanshu Umalkar

1

删除配置文件中 renew_lifetime = 7d 行的替代(并且更好)的方法是允许主体进行续订。在CentOS 7中,示例命令如下:

kadmin -p admin/admin@EXAMPLE.COM

假设admin/admin@EXAMPLE.COM是管理员主体,那么:

modprinc -maxrenewlife 90day +allow_renewable your_service@EXAMPLE.COM

我假设导致问题的服务负责人是your_service@EXAMPLE.COM;而90day的续订周期是任意的。

这解决了问题,不需要krb5.conf文件中删除renew_lifetime=7d


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接