浏览器不断发送 NTLM 令牌而不是 Kerberos - 如何解决? [英] Browsers keeps sending NTLM token instead of Kerberos - How to solve it?

查看:28
本文介绍了浏览器不断发送 NTLM 令牌而不是 Kerberos - 如何解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法正确配置系统并让浏览器发送 已配置 Jetty/SPNEgo 支持的 Web 应用程序.

  • OTHER.COMPANY.local(在 192.168.0.9 上),只是一个客户端,所以我可以从另一台机器访问软件服务器.
  • 最后两个实际上是运行在内网linux服务器上的VM.他们可以通过自己的 IP 访问.他们在网络配置中的主要DNS指向192.168.0.5.

    两者都加入 COMPANY.local 并在 AD 中作为计算机出现.

    我知道客户端和服务器

    Internet Explorer(以及 Chrome)在 Internet 选项 中有以下设置:

    安全性>本地内联网网站 >*.company.local安全自定义级别仅内网区域自动登录

    当我在 http://software.company.local:8998/software/login

    上访问 Web 应用程序时

    我可以看到浏览器发送了一个NTLM请求

    并且我可以在服务器端看到 网络应用程序已注册为 Windows 服务器.

    这些是配置文件:

    krb5.ini 文件:

    [libdefaults]default_realm = COMPANY.LOCALallowed_enctypes = rc4-hmac,aes128-cts,aes256-cts,arcfour-hmac-md5,aes256-cts-hmac-sha1-96default_tgs_enctypes = rc4-hmac,aes128-cts,aes256-cts,arcfour-hmac-md5,aes256-cts-hmac-sha1-96default_tkt_enctypes = rc4-hmac,aes128-cts,aes256-cts,arcfour-hmac-md5,aes256-cts-hmac-sha1-96default_keytab_name = FILE:C:/software/inst/modules/common-config/krb5.keytab[domain_realm]公司.本地 = 公司.本地.company.local = 公司.本地[领域]公司.本地 = {admin_server = PC-I7.COMPANY.localkdc = PC-I7.COMPANY.local:88}

    spnego.conf 文件:

    com.sun.security.jgss.initiate {需要 com.sun.security.auth.module.Krb5LoginModuleprincipal = "HTTP/software.company.local@COMPANY.LOCAL"keyTab = "C:/software/inst/modules/common-config/auth/krb5.keytab"useKeyTab = 真商店密钥 = 真调试 = 真isInitiator = false;};com.sun.security.jgss.accept {需要 com.sun.security.auth.module.Krb5LoginModuleprincipal = "HTTP/software.company.local@COMPANY.LOCAL"useKeyTab = 真keyTab = "C:/software/inst/modules/common-config/auth/krb5.keytab"存储键=真调试=真isInitiator=false;};

    这是 spnego.properties 文件:

    targetName = HTTP/software.company.local

    我的jetty-web.xml 配置文件包含:

    <设置名称=登录服务"><New class="org.eclipse.jetty.security.SpnegoLoginService"><Set name="name">公司领域</Set><设置名称=配置"><SystemProperty name="jetty.home" default="."/>/modules/common-config/auth/spnego.properties</Set></新的></设置><设置名称="checkWelcomeFiles">true</Set></获取>

    这是我在 Java 中以编程方式注册 spnego 配置的方式:

    private SecurityHandler wrapEnableSSOAuthHandlers(final Handler collection) {//ini文件System.setProperty("java.security.krb5.conf",_config.getString("authentication.win_sso.spnego.krb5")//krb5.ini 文件);System.setProperty("java.security.auth.login.config",_config.getString("authentication.win_sso.spnego.login")//spnego.conf 文件);System.setProperty("javax.security.auth.useSubjectCredsOnly",错误的");最终约束 spnegoConstraint = new Constraint();spnegoConstraint.setName(Constraint.__SPNEGO_AUTH);final String domainRealm = _config.getString("authentication.win_sso.domain.realm");//解析为 COMPANY.LOCALspnegoConstraint.setRoles(new String[]{domainRealm});spnegoConstraint.setAuthenticate(true);最终 ConstraintMapping 映射 = new ConstraintMapping();mapping.setConstraint(spnegoConstraint);mapping.setPathSpec("/*");最终字符串 spnegoProperties = _config.getString("authentication.win_sso.spnego.properties");//spnego.properties 文件final SpnegoLoginService loginService = new SpnegoLoginService();loginService.setConfig(spnegoProperties);loginService.setName(domainRealm);final ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();securityHandler.setLoginService(loginService);securityHandler.setConstraintMappings(new ConstraintMapping[]{mapping});securityHandler.setRealmName(domainRealm);securityHandler.setAuthenticator(new SpnegoAuthenticator());securityHandler.setHandler(集合);返回 securityHandler;}

    //这里我禁用了所有调用的 TRACE 方法处理程序wrappedSecurityHandler = wrapDisableTraceHandlers(handlers);WrappedSecurityHandler = wrapEnableSSOAuthHandlers(wrappedSecurityHandler);_server.setHandler(wrappedSecurityHandler);

    <小时>

    编辑 1:附加信息

    我已经下载了 Kerberos 身份验证测试器工具,并从 KDC 服务器 (192.168.0.5) 运行它并针对 http://software.company.local:8998<进行测试/code> 它显示了正确的 Kerberos 身份验证.

    当从 192.168.0.10 服务器(浏览器所在的位置)运行它时,它说:

    <块引用>

    意外的授权标头

    和认证方法:NTLM.

    我想要么是 DNS 问题,要么是因为它们是同一台服务器上的两个 VM.

    解决方案

    显然,将客户端和服务器放在两个不同的虚拟机(在同一 物理服务器上!)可能会导致 NTLM 令牌.

    我认为 VM 会避开 client-and-server-on-the-same-机器问题.

    所以,如果你

    • 像我一样,正在使用位于同一台物理机器上的 VM 进行测试,并且
    • 已将一切设置正确,但仍然收到检测到有缺陷的令牌,

    您应该尝试从另一台计算机访问服务器(只要该计算机已加入公司域).

    I can't seem to correctly configure the system and have the browser send a ticket to the web-server. Instead, a NTLM token is sent.

    Q: How can I solve this?

    All details and configurations are listed below.


    Infrastructure:

    I have three machines within the domain COMPANY.local:

    • PC-I7.COMPANY.local (on 192.168.0.5). It acts as KDC, it's an Active-Directory server with the other machines (see below) registered in the AD. Also has the DNS for the local network configured. The domain in the Active Directory is: COMPANY.local
    • SOFTWARE.COMPANY.local (on 192.168.0.10) runs the web-application which has the Jetty/SPNego support configured.
    • OTHER.COMPANY.local (on 192.168.0.9), just a client so I can access the software server from another machine.

    The last two are actually VMs running on a linux server in the intranet. They are reachable with their own IP. Their primary DNS in Network Configuration points to 192.168.0.5.

    Both are joined in COMPANY.local and are present as computers in the AD.

    I know client and server should stay on different machines; and being them onto two different VM's should avoid this issue.

    All three machines are registered as A hosts in the DNS with a reverse pointer for each of them in the Reverse lookup zone.


    SPN

    After having created the user software in the Active Directory, I generate the keytab file

    ktpass -princ HTTP/software.company.local@COMPANY.LOCAL -mapuser software@COMPANY.LOCAL -crypto ALL -ptype KRB5_NT_PRINCIPAL -pass __PassForADUserSoftware__ -out C:/winnt/krb5.keytab
    

    I get the following output which seems to contain an error:

    Targeting domain controller: PC-I7.COMPANY.local
      Failed to set property 'userPrincipalName' to 'HTTP/software.company.local@COMPANY.LOCAL' on Dn 'CN=Software SSO Kerberized WebServer,DC=COMPANY,DC=local': 0x13.
      WARNING: Failed to set UPN HTTP/software.company.local@COMPANY.LOCAL on CN=Software SSO Kerberized WebServer,DC=COMPANY,DC=local.
      kinits to 'HTTP/software.company.local@COMPANY.LOCAL' will fail.
    Successfully mapped HTTP/software.company.local to software.
    Password successfully set!
    Key created.
    Key created.
    Key created.
    Key created.
    Key created.
    Output keytab to C:/winnt/krb5.keytab:
    Keytab version: 0x502 
    keysize 64 HTTP/software.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 8 etype 0x1 (DES-CBC-CRC) keylength 8 (0x0bf1688040abadba)
    keysize 64 HTTP/software.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 8 etype 0x3 (DES-CBC-MD5) keylength 8 (0x0bf1688040abadba)
    keysize 72 HTTP/software.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 8 etype 0x17 (RC4-HMAC) keylength 16 (0x737d9811dd38e108741461ba79153192)
    keysize 88 HTTP/software.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 8 etype 0x12 (AES256-SHA1) keylength 32 (0xcc8ab2939f822f9df6904a987954e0cfaa261bc36803af6c5f8d9a98f1d4f2aa)
    keysize 72 HTTP/software.company.local@COMPANY.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 8 etype 0x11 (AES128-SHA1) keylength 16 (0xd616b814dcd1b955f125ab4de5895d39)
    

    The AD user has the two This account supports the Kerbers AES-... checkboxes checked.


    The OTHER.COMPANY.local server

    I login to this machine via RDP with the credentials:

    user: Administrator
    pass: ARandomPass
    

    When asking for a ticket from OTHER server with

    kinit HTTP/software.company.local@COMPANY.LOCAL
    

    I can see this packets with wireshark

    Internet explorer (and therefore Chrome) have the following settings in Internet Options:

    Security > Local Intranet > Sites > *.company.local
    Security > Custom level > Automatic logon only in Intranet area
    

    When I reach the web application on http://software.company.local:8998/software/login

    I can see the browser sends a NTLM request

    and I can see the Defective Token exception on the server side

    WARN:oejs.SpnegoLoginService:qtp506835709-28: 
    GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
    at sun.security.jgss.GSSHeader.<init>(GSSHeader.java:97)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:306)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
    at org.eclipse.jetty.security.SpnegoLoginService.login(SpnegoLoginService.java:138)
    at org.eclipse.jetty.security.authentication.LoginAuthenticator.login(LoginAuthenticator.java:61)
    at org.eclipse.jetty.security.authentication.SpnegoAuthenticator.validateRequest(SpnegoAuthenticator.java:99)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:483)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:524)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
    at java.lang.Thread.run(Thread.java:748)
    

    Also this info appears in the java log:

    Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt false 
    ticketCache is null isInitiator false 
    KeyTab is C:/software/inst/modules/common-config/auth/krb5.keytab refreshKrb5Config is false 
    principal is HTTP/software.company.local@COMPANY.LOCAL tryFirstPass is false 
    useFirstPass is false storePass is false clearPass is false
    

    Information I can gather from the linked answer:

    • Point 1: The SPN for the HTTP service does match the URL entered by the browser. I input software.company.local in the browser which is the same as the SPN HTTP/software.company.local@COMPANY.LOCAL

    • Point 2: *.company.local is added to the trusted sites.

    • Point 3: I'm not restricting the encrpytion to DES-CBC-MD5

    • Point 3: I have checked AES-128 and AES-256 ... but not DES because the Windows Server version I am working with has the checkbox saying Use only Kerberos DES encryption types for this account, which is not what I want. Should I check it?


    The SOFTWARE.COMPANY.local server

    The web-application is registered as a Windows Server.

    These are the configuration files:

    krb5.ini file:

    [libdefaults]
    default_realm = COMPANY.LOCAL
    permitted_enctypes = rc4-hmac,aes128-cts,aes256-cts,arcfour-hmac-md5,aes256-cts-hmac-sha1-96    
    default_tgs_enctypes = rc4-hmac,aes128-cts,aes256-cts,arcfour-hmac-md5,aes256-cts-hmac-sha1-96
    default_tkt_enctypes = rc4-hmac,aes128-cts,aes256-cts,arcfour-hmac-md5,aes256-cts-hmac-sha1-96
    default_keytab_name = FILE:C:/software/inst/modules/common-config/krb5.keytab
    
    [domain_realm]
    COMPANY.local = COMPANY.LOCAL
    .company.local = COMPANY.LOCAL
    
    [realms]
    COMPANY.LOCAL = {
        admin_server = PC-I7.COMPANY.local
        kdc = PC-I7.COMPANY.local:88
    }
    

    spnego.conf file:

    com.sun.security.jgss.initiate {
        com.sun.security.auth.module.Krb5LoginModule required
        principal = "HTTP/software.company.local@COMPANY.LOCAL"
        keyTab = "C:/software/inst/modules/common-config/auth/krb5.keytab"
        useKeyTab = true
        storeKey = true
        debug = true
        isInitiator = false;
    };
    
    com.sun.security.jgss.accept {
        com.sun.security.auth.module.Krb5LoginModule required
        principal = "HTTP/software.company.local@COMPANY.LOCAL"
        useKeyTab = true
        keyTab = "C:/software/inst/modules/common-config/auth/krb5.keytab"
        storeKey=true
        debug=true
        isInitiator=false;
    };
    

    and this is the spnego.properties file:

    targetName = HTTP/software.company.local
    

    My jetty-web.xml configuration file contains:

    <Get name="securityHandler">
        <Set name="loginService">
            <New class="org.eclipse.jetty.security.SpnegoLoginService">
                <Set name="name">Company Realm</Set>
                <Set name="config">
                    <SystemProperty name="jetty.home" default="."/>/modules/common-config/auth/spnego.properties</Set>
            </New>
        </Set>
        <Set name="checkWelcomeFiles">true</Set>
    </Get>
    

    This is how I programmatically register the spnego configuration in Java:

    private SecurityHandler wrapEnableSSOAuthHandlers(final Handler collection) {
    
        // ini file
        System.setProperty(
                "java.security.krb5.conf",
                _config.getString("authentication.win_sso.spnego.krb5") // the krb5.ini file
        );
        System.setProperty(
                "java.security.auth.login.config",
                _config.getString("authentication.win_sso.spnego.login") // the spnego.conf file
        );
        System.setProperty(
                "javax.security.auth.useSubjectCredsOnly",
                "false"
        );
    
        final Constraint spnegoConstraint = new Constraint();
        spnegoConstraint.setName(Constraint.__SPNEGO_AUTH);
    
        final String domainRealm = _config.getString("authentication.win_sso.domain.realm");    // resolves to COMPANY.LOCAL
    
        spnegoConstraint.setRoles(new String[]{domainRealm});
        spnegoConstraint.setAuthenticate(true);
    
        final ConstraintMapping mapping = new ConstraintMapping();
        mapping.setConstraint(spnegoConstraint);
        mapping.setPathSpec("/*");
    
        final String spnegoProperties = _config.getString("authentication.win_sso.spnego.properties");      // the spnego.properties file
    
        final SpnegoLoginService loginService = new SpnegoLoginService();
        loginService.setConfig(spnegoProperties);
        loginService.setName(domainRealm);
    
        final ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
        securityHandler.setLoginService(loginService);
        securityHandler.setConstraintMappings(new ConstraintMapping[]{mapping});
        securityHandler.setRealmName(domainRealm);
        securityHandler.setAuthenticator(new SpnegoAuthenticator());
        securityHandler.setHandler(collection);
        return securityHandler;
    }
    

    and

    // here I disable the TRACE method for all calls 
    Handler wrappedSecurityHandler = wrapDisableTraceHandlers(handlers);
    wrappedSecurityHandler = wrapEnableSSOAuthHandlers(wrappedSecurityHandler);
    _server.setHandler(wrappedSecurityHandler);
    


    EDIT 1: Additional info

    I have downloaded the Kerberos Authentication Tester Tool and when running it from the KDC server (192.168.0.5) and testing against http://software.company.local:8998 it shows a correct Kerberos authentication.

    When running it from the 192.168.0.10 server (where the browser is) it says:

    Unexpected authorization header

    and authentication method: NTLM.

    I guess it's either a DNS issue or the fact that they are two VM on the same server.

    解决方案

    Apparently, having client and server on two distinct virtual machines ( that are on the same physical server! ) can lead to a NTLM token.

    I thought VM's would dodge the client-and-server-on-the-same-machine-issue.

    So, if you

    • like me, are testing with VM's residing on the same physical machine, and
    • have set everything right but still getting a Defective token detected,

    you should try to access the server from a different computer (as long as that machine is joined to the company domain).

    这篇关于浏览器不断发送 NTLM 令牌而不是 Kerberos - 如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆