如何修复由于“无法从用户获取密码”导致Tomcat Windows身份验证导致的“无法登录为服务主体”异常?

问题描述 投票:1回答:1

我正在尝试使用其内置支持为Tomcat8.0 webapps实现Windows身份验证。我在TOMCAT_HOME \ logs \ tomcat8-stderr.2017-03-17.log文件中收到以下异常: -

17-Mar-2017 10:59:39.367 FINE [http-nio-8080-exec-6] org.apache.catalina.authenticator.AuthenticatorBase.invoke Security checking request GET /testad/
17-Mar-2017 10:59:39.367 FINE [http-nio-8080-exec-6] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[Common Area]' against GET /index.jsp --> true
17-Mar-2017 10:59:39.367 FINE [http-nio-8080-exec-6] org.apache.catalina.realm.RealmBase.findSecurityConstraints   Checking constraint 'SecurityConstraint[Common Area]' against GET /index.jsp --> true
17-Mar-2017 10:59:39.367 FINE [http-nio-8080-exec-6] org.apache.catalina.authenticator.AuthenticatorBase.invoke  Calling hasUserDataPermission()
17-Mar-2017 10:59:39.367 FINE [http-nio-8080-exec-6] org.apache.catalina.realm.RealmBase.hasUserDataPermission   User data constraint has no restrictions
17-Mar-2017 10:59:39.367 FINE [http-nio-8080-exec-6] org.apache.catalina.authenticator.AuthenticatorBase.invoke  Calling authenticate()
17-Mar-2017 10:59:39.383 SEVERE [http-nio-8080-exec-6] org.apache.catalina.authenticator.SpnegoAuthenticator.doAuthenticate Unable to login as the service principal
 javax.security.auth.login.LoginException: Unable to obtain password from user

    at com.sun.security.auth.module.Krb5LoginModule.promptForPass(Unknown Source)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Unknown Source)
    at com.sun.security.auth.module.Krb5LoginModule.login(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at javax.security.auth.login.LoginContext.invoke(Unknown Source)
    at javax.security.auth.login.LoginContext.access$000(Unknown Source)
    at javax.security.auth.login.LoginContext$4.run(Unknown Source)
    at javax.security.auth.login.LoginContext$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
    at javax.security.auth.login.LoginContext.login(Unknown Source)
    at org.apache.catalina.authenticator.SpnegoAuthenticator.doAuthenticate(SpnegoAuthenticator.java:197)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:556)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

17-Mar-2017 10:59:39.383 FINE [http-nio-8080-exec-6] org.apache.catalina.authenticator.AuthenticatorBase.invoke  Failed authenticate() test

以下是我的环境细节: -

  1. AD的Windows Server 2012(FQDN:dev.devdevelopment.com)
  2. 用于Apache Tomcat 8.5.11和Java 1.8.0_31(64位)的Windows 7计算机(FQDN:windows7devpc.devdevelopment.com)
  3. Windows XP机器作为客户端(Firefox浏览器)
  4. AD域名:devdevelopment.com

我有一个域用户devtomcat,以下SPN映射到:

enter image description here

我有另一个域用户devuser,它是名为tc-webapp-users的组的成员,该组位于名为tomcat-ou的OU中。该用户用于从windows xp机器访问webapp。

enter image description here

以下是我的tomcat的server.xml

<?xml version="1.0" encoding="UTF-8"?>

<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources/>

  <Service name="Catalina">
    <Connector port="8080" maxSavePostSize="2097152" URIEncoding="UTF-8" maxHttpHeaderSize="65536"/>
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
        <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
            <Context docBase="testad" path="/testad">
                <Realm className="org.apache.catalina.realm.JNDIRealm"
                        connectionURL="ldap://dev.devdevelopment.com:389"
                        userSubtree="true"
                        userBase="CN=Users,DC=devdevelopment,DC=com"
                        userSearch="(sAMAccountName={0})"
                        userRoleName="memberOf"
                        roleBase="CN=tc-webapp-users,OU=tomcat-ou,DC=devdevelopment,DC=com"
                        roleName="cn"
                        roleSearch="(member={0})"
                        roleSubtree="true"
                        roleNested="true"/>
                <Valve className="org.apache.catalina.authenticator.SpnegoAuthenticator" storeDelegatedCredential="true"/>
            </Context>
        </Host>
    </Engine>
  </Service>
</Server>

以下是webapp的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Common Area</web-resource-name>
            <url-pattern>/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
            <http-method>PUT</http-method>
            <http-method>HEAD</http-method>
            <http-method>TRACE</http-method>
            <http-method>DELETE</http-method>
            <http-method>OPTIONS</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>tc-webapp-users</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>SPNEGO</auth-method>
    </login-config>

    <security-role>
        <description>TC-WebApp-Roles</description>
        <role-name>tc-webapp-users</role-name>
    </security-role>
</web-app>

以下是krb5.ini文件的内容,该文件位于C:\ Program Files \ Apache Software Foundation \ Tomcat 8.5 \ conf目录下: -

[libdefaults]
default_realm=DEVDEVELOPMENT.COM
default_keytab_name=“C:/Program Files/Apache Software Foundation/Tomcat 8.5/conf/tomcat.keytab"
default_tkt_enctypes=rc4-hmac,aes256-cts-hmac-shal-96,aes128-cts-hmac-shal-96
default_tgs_enctypes=rc4-hmac,aes256-cts-hmac-shal-96,aes128-cts-hmac-shal-96
permitted_enctypes=rc4-hmac,aes256-cts-hmac-shal-96,aes128-cts-hmac-shal-96
udp_preference_limit=1
forwardable=true

[realms]
DEVDEVELOPMENT.COM={
    kdc=dev.devdevelopment.com
}

[domain_realm]
devdevelopment.com=DEVDEVELOPMENT.COM
.devdevelopment.com=DEVDEVELOPMENT.COM

以下是jaas.conf文件的内容,该文件位于C:\ Program Files \ Apache Software Foundation \ Tomcat 8.5 \ conf目录下: -

com.sun.security.jgss.krb5.accept {
    com.sun.security.auth.module.Krb5LoginModule required
    doNotPrompt=true
    principal="HTTP/[email protected]"
    keyTab="C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\tomcat.keytab"
    storeKey=true
    useKeyTab=true
    useTicketCache=true
    isInitiator=true
    refreshKrb5Config=true
    moduleBanner=true
    storePass=true;
};

com.sun.security.jgss.krb5.initiate {
    com.sun.security.auth.module.Krb5LoginModule required
    doNotPrompt=true
    principal="HTTP/[email protected]"
    keyTab="C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\tomcat.keytab"
    storeKey=true
    useKeyTab=true
    useTicketCache=true
    isInitiator=true
    refreshKrb5Config=true
    moduleBanner=true
    storePass=true
    debug=true;
};

以下是JDK的klist命令的诊断输出(在Tomcat机器上运行): -

c:\Program Files\Java\jdk1.8.0_31\bin>klist -e -k -t "C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\tomcat.keytab"

Key tab: C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\tomcat.keytab, 1 entry found.

[1] Service principal: HTTP/[email protected]
         KVNO: 12
         Key type: 18
         Time stamp: Jan 01, 1970 05:30:00

以下是调试模式下JDK的kinit命令(在Tomcat机器上运行)的诊断输出: -

c:\Program Files\Java\jdk1.8.0_31\bin>kinit -J-Dsun.security.krb5.debug=true -k -t "C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\tomcat.keytab" HTTP/[email protected]
>>>KinitOptions cache name is C:\Users\devtomcat\krb5cc_devtomcat
Principal is HTTP/[email protected]
>>> Kinit using keytab
>>> Kinit keytab file name: C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\tomcat.keytab
Java config name: null
LSA: Found Ticket
LSA: Made NewWeakGlobalRef
LSA: Found PrincipalName
LSA: Made NewWeakGlobalRef
LSA: Found DerValue
LSA: Made NewWeakGlobalRef
LSA: Found EncryptionKey
LSA: Made NewWeakGlobalRef
LSA: Found TicketFlags
LSA: Made NewWeakGlobalRef
LSA: Found KerberosTime
LSA: Made NewWeakGlobalRef
LSA: Found String
LSA: Made NewWeakGlobalRef
LSA: Found DerValue constructor
LSA: Found Ticket constructor
LSA: Found PrincipalName constructor
LSA: Found EncryptionKey constructor
LSA: Found TicketFlags constructor
LSA: Found KerberosTime constructor
LSA: Finished OnLoad processing
Native config name: C:\Windows\krb5.ini
>>> Kinit realm name is DEVDEVELOPMENT.COM
>>> Creating KrbAsReq
>>> KrbKdcReq local addresses for windows7devpc are:

        windows7devpc/192.168.1.229
IPv4 address

        windows7devpc/fe80:0:0:0:80f2:1a68:c0f0:710%11
IPv6 address
>>> KdcAccessibility: reset
>>> KeyTabInputStream, readName(): DEVDEVELOPMENT.COM
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): windows7devpc.devdevelopment.com
>>> KeyTab: load() entry length: 107; type: 18
Looking for keys for: HTTP/[email protected]
Added key: 18version: 12
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 16 23.
>>> KrbAsReq creating message
getKDCFromDNS using UDP
>>> KrbKdcReq send: kdc=dev.devdevelopment.com. UDP:88, timeout=30000, number of retries =3, #bytes=227
>>> KDCCommunication: kdc=dev.devdevelopment.com. UDP:88, timeout=30000,Attempt =1, #bytes=227
>>> KrbKdcReq send: #bytes read=227
>>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 18, salt = DEVDEVELOPMENT.COMHTTPwindows7devpc.devdevelopment.com, s2kparams = null

>>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
         PA-DATA type = 16

>>>Pre-Authentication Data:
         PA-DATA type = 15

>>> KdcAccessibility: remove dev.devdevelopment.com.:88
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
         sTime is Thu Mar 16 22:50:19 IST 2017 1489684819000
         suSec is 759798
         error code is 25
         error Message is Additional pre-authentication required
         sname is krbtgt/[email protected]
         eData provided.
         msgType is 30
>>>Pre-Authentication Data:
         PA-DATA type = 19
         PA-ETYPE-INFO2 etype = 18, salt = DEVDEVELOPMENT.COMHTTPwindows7devpc.devdevelopment.com, s2kparams = null

>>>Pre-Authentication Data:
         PA-DATA type = 2
         PA-ENC-TIMESTAMP
>>>Pre-Authentication Data:
         PA-DATA type = 16

>>>Pre-Authentication Data:
         PA-DATA type = 15

KrbAsReqBuilder: PREAUTH FAILED/REQ, re-send AS-REQ
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 16 23.
Looking for keys for: HTTP/[email protected]
Added key: 18version: 12
Looking for keys for: HTTP/[email protected]
Added key: 18version: 12
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 18 17 16 23.
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
>>> KrbAsReq creating message
getKDCFromDNS using UDP
>>> KrbKdcReq send: kdc=dev.devdevelopment.com. UDP:88, timeout=30000, number of retries =3, #bytes=316
>>> KDCCommunication: kdc=dev.devdevelopment.com. UDP:88, timeout=30000,Attempt =1, #bytes=316
>>> KrbKdcReq send: #bytes read=108
>>> KrbKdcReq send: kdc=dev.devdevelopment.com. TCP:88, timeout=30000, number of retries =3, #bytes=316
>>> KDCCommunication: kdc=dev.devdevelopment.com. TCP:88, timeout=30000,Attempt =1, #bytes=316
>>>DEBUG: TCPClient reading 1766 bytes
>>> KrbKdcReq send: #bytes read=1766
>>> KdcAccessibility: remove dev.devdevelopment.com.:88
Looking for keys for: HTTP/[email protected]
Added key: 18version: 12
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
>>> KrbAsRep cons in KrbAsReq.getReply HTTP/windows7devpc.devdevelopment.com
New ticket is stored in cache file C:\Users\devtomcat\krb5cc_devtomcat

以下是在Tomcat8属性窗口的Java选项卡中设置的Java环境变量: -

enter image description here

最后,以下是在域用户devuser的Windows xp机器上的Firefox浏览器中完成的设置: -

enter image description here

enter image description here

在Windows XP机器中访问webapp时,tomcat机器中的Wireshark登录不显示任何条目/活动。我怀疑是否由tomcat机器启动了SPNEGO协商。

krb5.ini文件应该放在C:\ Windows目录中吗?此外,keytab文件路径中的空格是否重要?

我按照here提到的说明进行操作。在哪里以及我做错了什么/遗失了什么?

java-ee windows-authentication kerberos tomcat8 spnego
1个回答
0
投票

jaas.conf中,包含debug=true,因此它将打印使用过的keytab文件名和其他有用的信息。

您将看到keytab文件名作为转义的java字符串处理,因此您应该将双反斜杠写为路径分隔符。相当棘手的问题。

© www.soinside.com 2019 - 2024. All rights reserved.