我正在尝试使用Kerberos在Tomcat 9(使用SDK 8)中配置SSO。我的环境全部在Windows Server 2016 VM中:-
我经历了很多教程(所有教程都稍有不同),但是仍然无法访问我的网页,401一直在等着我。
AD中的域为“ FORESTGUMP.INTERNAL”(是的。在使用单个“ R”拼写森林的过程中没有错,只是凌晨2点的虚构名称)。我在此域中创建了2个用户
我将SPN映射到tomcat用户:
setspn -l forestgump.internal\tomcat Registered ServicePrincipalNames for CN=tomcat,CN=Users,DC=forestgump,DC=internal: HTTP/[email protected] HTTP/[email protected] HTTP/windowstomcat HTTP/windowstomcat.forestgump.internal
然后我生成了一个密钥表文件:
ktpass /out c:\tomcat.keytab /mapuser [email protected] /princ HTTP/[email protected] /pass Passw0rd! /kvno 0 -crypto ALL -ptype KRB5_NT_PRINCIPAL
并将此tomcat.keytab复制到Tomcat服务器./tomcat-9/conf,并在c。\ tomcat-9 \ lib中添加了spnego-r9.jar
在tomcat服务器中,我创建了文件./tomcat-9/conf/krb5.ini
[libdefaults] default_realm = FORESTGUMP.INTERNAL default_keytab_name = "C:\opt\tomcat-9\conf\tomcat.keytab" default_tkt_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96 default_tgs_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96 forwardable=true [realms] forestgump.internal = { kdc = server2016.forestgump.internal:88 } [domain_realm] forestgump.internal= FORESTGUMP.INTERNAL .forestgump.internal= FORESTGUMP.INTERNAL
并且我创建了文件./tomcat-9/conf/jass.conf
com.sun.security.jgss.krb5.initiate { com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=true principal="HTTP/[email protected]" keyTab="c:/opt/tomcat-9/conf/tomcat.keytab" useKeyTab=true storeKey=true; debug=true; }; com.sun.security.jgss.krb5.accept { com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=true principal="HTTP/[email protected]" keyTab="c:/opt/tomcat-9/conf/tomcat.keytab" useKeyTab=true storeKey=true; debug=true; };
到目前为止,在我发现的所有教程中,它都非常一致。从现在开始,遥远的西部以及我对tomcat和Java开发的了解不足无济于事。我更改了默认tomcat-9 / conf / server.xml,为AD LDAP添加了一个领域]
<Realm className="org.apache.catalina.realm.LockOutRealm"> <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm. --> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" /> <Realm className="org.apache.catalina.realm.JNDIRealm" connectionURL="ldap://server2016.forestgump.internal:389" authentication="simple" referrals="follow" connectionName="CN=tomcat,CN=Users,DC=forestgump,DC=internal" connectionPassword="Passw0rd!" userSearch="(sAMAccountName={0})" userBase="CN=Users,DC=forestgump,DC=internal" userSubtree="true" roleSearch="(member={0})" roleName="cn" roleSubtree="true" roleBase="cn=Builtin,DC=forestgump,DC=internal" /> </Realm>
我使用Jxplorer测试了LDAP的配置,并且可以连接到我的AD。不知道这是否完全必要,我发现的教程中只有20%提到了这一点。
然后,我创建了一个简单的Web应用程序以测试配置。 Web应用程序具有以下结构:
这里的文件内容
index.jsp
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>AUTH test</title> </head> <body> <h1>Hello World!</h1> <p>auth type: <%=request.getAuthType()%> </p> <p>remote user: <%=request.getRemoteUser() %> </p> <p>principal: <%=request.getUserPrincipal() %></p> <p>name: <%= (request.getUserPrincipal()!=null)?request.getUserPrincipal().getName():"NO PRINCIPAL" %></p> </body> </html>
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Web Resource - Allow GET method</web-resource-name> <url-pattern>/*</url-pattern> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <role-name>CN=Users,DC=forestgump,DC=internal</role-name> </auth-constraint> </security-constraint> <security-role> <role-name>CN=Users,DC=forestgump,DC=internal</role-name> </security-role> <login-config> <auth-method>SPNEGO</auth-method> <realm-name>FORESTGUMP.INTERNAL</realm-name> </login-config> </web-app>
context.xml
<?xml version="1.0" encoding="UTF-8"?> <Context antiJARLocking="true" path="/spnego"> <!-- valve will be explicitly created when SPNEGO is used, this is to declare additional attributes --> <Valve className="org.apache.catalina.authenticator.SpnegoAuthenticator" alwaysUseSession="true" cache="true" /> </Context>
在客户端虚拟机中,我使用IE,Firefox(配置为network.negotiate-auth.delegation-uris = windowstomcat.forestgump.internal和network.negotiate-auth.gsslib = windowstomcat.forestgump.internal)和Kerberos身份验证客户端([ C0])
结果总是来自浏览器的401和Kerberos测试器的500。
真正令人沮丧的是,我看不到tomcat或AD中的任何错误。在tomcat中,我甚至在启动时添加了调试语句(设置CATALINA_OPTS = -Dsun.security.krb5.debug = true -Dsun.security.jgss.debug = true -Dsun.security.spnego.debug = true)。
catalina.log非常干净localhost.log有几个例外(当我使用Kerberos客户端测试并获得500时)
http://blog.michelbarneveld.nl/michel/archive/2009/12/05/kerberos-authentication-tester.aspx这绝对与我的web应用有关,但是我无法确定是什么导致了错误。
任何帮助都会极大地帮助我提高理智。干杯。
在删除配置文件中的分号的建议之后,我继续前进,现在得到一些有趣的异常:
08-May-2020 14:51:46.294 SEVERE [http-nio-8080-exec-4] org.apache.catalina.core.StandardHostValve.invoke Exception Processing /TomcatHelloWorld/ java.lang.SecurityException: java.io.IOException: Configuration Error: Line 8: expected [controlFlag] at sun.security.provider.ConfigFile$Spi.<init>(ConfigFile.java:137) at sun.security.provider.ConfigFile.<init>(ConfigFile.java:102) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at java.lang.Class.newInstance(Class.java:442) at javax.security.auth.login.Configuration$2.run(Configuration.java:255) at javax.security.auth.login.Configuration$2.run(Configuration.java:247) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:246) at javax.security.auth.login.LoginContext$1.run(LoginContext.java:245) at javax.security.auth.login.LoginContext$1.run(LoginContext.java:243) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.login.LoginContext.init(LoginContext.java:243) at javax.security.auth.login.LoginContext.<init>(LoginContext.java:348) at org.apache.catalina.authenticator.SpnegoAuthenticator.doAuthenticate(SpnegoAuthenticator.java:196) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:631) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748) Caused by: java.io.IOException: Configuration Error: Line 8: expected [controlFlag] at sun.security.provider.ConfigFile$Spi.ioException(ConfigFile.java:666) at sun.security.provider.ConfigFile$Spi.match(ConfigFile.java:572) at sun.security.provider.ConfigFile$Spi.parseLoginEntry(ConfigFile.java:454) at sun.security.provider.ConfigFile$Spi.readConfig(ConfigFile.java:427) at sun.security.provider.ConfigFile$Spi.init(ConfigFile.java:329) at sun.security.provider.ConfigFile$Spi.init(ConfigFile.java:271) at sun.security.provider.ConfigFile$Spi.<init>(ConfigFile.java:135) ... 31 more
我在Kerberos服务器中添加了256个支持:
11-May-2020 14:38:55.976 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [897] milliseconds Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is c:/opt/tomcat-9/conf/tomcat.keytab refreshKrb5Config is false principal is HTTP/[email protected] tryFirstPass is false useFirstPass is false storePass is false clearPass is false >>> KeyTabInputStream, readName(): FORESTGUMP.INTERNAL >>> KeyTabInputStream, readName(): HTTP >>> KeyTabInputStream, readName(): windowstomcat.forestgump.internal >>> KeyTab: load() entry length: 85; type: 1 >>> KeyTabInputStream, readName(): FORESTGUMP.INTERNAL >>> KeyTabInputStream, readName(): HTTP >>> KeyTabInputStream, readName(): windowstomcat.forestgump.internal >>> KeyTab: load() entry length: 85; type: 3 >>> KeyTabInputStream, readName(): FORESTGUMP.INTERNAL >>> KeyTabInputStream, readName(): HTTP >>> KeyTabInputStream, readName(): windowstomcat.forestgump.internal >>> KeyTab: load() entry length: 93; type: 23 >>> KeyTabInputStream, readName(): FORESTGUMP.INTERNAL >>> KeyTabInputStream, readName(): HTTP >>> KeyTabInputStream, readName(): windowstomcat.forestgump.internal >>> KeyTab: load() entry length: 109; type: 18 >>> KeyTabInputStream, readName(): FORESTGUMP.INTERNAL >>> KeyTabInputStream, readName(): HTTP >>> KeyTabInputStream, readName(): windowstomcat.forestgump.internal >>> KeyTab: load() entry length: 93; type: 17 Looking for keys for: HTTP/[email protected] Java config name: C:\opt\tomcat-9\conf\krb5.ini Loaded from Java config Added key: 17version: 0 Added key: 18version: 0 Added key: 23version: 0 Found unsupported keytype (3) for HTTP/[email protected] Found unsupported keytype (1) for HTTP/[email protected] >>> KdcAccessibility: reset Looking for keys for: HTTP/[email protected] Added key: 17version: 0 Added key: 18version: 0 Added key: 23version: 0 Found unsupported keytype (3) for HTTP/[email protected] Found unsupported keytype (1) for HTTP/[email protected] default etypes for default_tkt_enctypes: 23 18 17. >>> KrbAsReq creating message getKDCFromDNS using UDP >>> KrbKdcReq send: kdc=server2016.forestgump.internal. UDP:88, timeout=30000, number of retries =3, #bytes=190 >>> KDCCommunication: kdc=server2016.forestgump.internal. UDP:88, timeout=30000,Attempt =1, #bytes=190 >>> KrbKdcReq send: #bytes read=238 >>>Pre-Authentication Data: PA-DATA type = 19 PA-ETYPE-INFO2 etype = 18, salt = FORESTGUMP.INTERNALHTTPwindowstomcat.forestgump.internal, s2kparams = null PA-ETYPE-INFO2 etype = 23, salt = null, 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 server2016.forestgump.internal.:88 >>> KDCRep: init() encoding tag is 126 req type is 11 >>>KRBError: sTime is Mon May 11 14:39:04 NZST 2020 1589164744000 suSec is 480933 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 = FORESTGUMP.INTERNALHTTPwindowstomcat.forestgump.internal, s2kparams = null PA-ETYPE-INFO2 etype = 23, salt = null, 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 default etypes for default_tkt_enctypes: 23 18 17. Looking for keys for: HTTP/[email protected] Added key: 17version: 0 Added key: 18version: 0 Added key: 23version: 0 Found unsupported keytype (3) for HTTP/[email protected] Found unsupported keytype (1) for HTTP/[email protected] Looking for keys for: HTTP/[email protected] Added key: 17version: 0 Added key: 18version: 0 Added key: 23version: 0 Found unsupported keytype (3) for HTTP/[email protected] Found unsupported keytype (1) for HTTP/[email protected] default etypes for default_tkt_enctypes: 23 18 17. >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType >>> KrbAsReq creating message getKDCFromDNS using UDP >>> KrbKdcReq send: kdc=server2016.forestgump.internal. UDP:88, timeout=30000, number of retries =3, #bytes=279 >>> KDCCommunication: kdc=server2016.forestgump.internal. UDP:88, timeout=30000,Attempt =1, #bytes=279 >>> KrbKdcReq send: #bytes read=110 >>> KrbKdcReq send: kdc=server2016.forestgump.internal. TCP:88, timeout=30000, number of retries =3, #bytes=279 >>> KDCCommunication: kdc=server2016.forestgump.internal. TCP:88, timeout=30000,Attempt =1, #bytes=279 >>>DEBUG: TCPClient reading 1694 bytes >>> KrbKdcReq send: #bytes read=1694 >>> KdcAccessibility: remove server2016.forestgump.internal.:88 Looking for keys for: HTTP/[email protected] Added key: 17version: 0 Added key: 18version: 0 Added key: 23version: 0 Found unsupported keytype (3) for HTTP/[email protected] Found unsupported keytype (1) for HTTP/[email protected] >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType >>> KrbAsRep cons in KrbAsReq.getReply HTTP/windowstomcat.forestgump.internal principal is HTTP/[email protected] Will use keytab Commit Succeeded Search Subject for SPNEGO ACCEPT cred (<<DEF>>, sun.security.jgss.spnego.SpNegoCredElement) Search Subject for Kerberos V5 ACCEPT cred (<<DEF>>, sun.security.jgss.krb5.Krb5AcceptCredential) Found KeyTab c:\opt\tomcat-9\conf\tomcat.keytab for HTTP/[email protected] Found KeyTab c:\opt\tomcat-9\conf\tomcat.keytab for HTTP/[email protected] Found ticket for HTTP/[email protected] to go to krbtgt/[email protected] expiring on Tue May 12 00:39:04 NZST 2020 Entered SpNegoContext.acceptSecContext with state=STATE_NEW SpNegoContext.acceptSecContext: receiving token = a0 8.. SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.113554.1.2.2 SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.48018.1.2.2 SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.30 SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.10 SpNegoToken NegTokenInit: reading Mech Token SpNegoContext.acceptSecContext: received token of type = SPNEGO NegTokenInit SpNegoContext: negotiated mechanism = 1.2.840.113554.1.2.2 Entered Krb5Context.acceptSecContext with state=STATE_NEW Looking for keys for: HTTP/[email protected] Added key: 17version: 0 Added key: 18version: 0 Added key: 23version: 0 Found unsupported keytype (3) for HTTP/[email protected] Found unsupported keytype (1) for HTTP/[email protected] >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType Using builtin default etypes for permitted_enctypes default etypes for permitted_enctypes: 18 17 16 23. >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType MemoryCache: add 1589164744/000073/52EB3DFA8A4B8EADDCE4B0019A0968EE/[email protected] to [email protected]|HTTP/[email protected] >>> KrbApReq: authenticate succeed. >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType >>>Delegated Creds have [email protected] sname=krbtgt/[email protected] authtime=null starttime=20200511023904Z endtime=20200511123904ZrenewTill=20200518023904Z Krb5Context setting peerSeqNumber to: 1464367068 >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType Krb5Context setting mySeqNumber to: 206741889 ... Search Subject for Kerberos V5 INIT cred (<<DEF>>, sun.security.jgss.krb5.Krb5InitCredential) Found ticket for HTTP/[email protected] to go to krbtgt/[email protected] expiring on Tue May 12 00:39:04 NZST 2020 Entered Krb5Context.initSecContext with state=STATE_NEW Found ticket for HTTP/[email protected] to go to krbtgt/[email protected] expiring on Tue May 12 00:39:04 NZST 2020 Service ticket not found in the subject >>> Credentials acquireServiceCreds: same realm default etypes for default_tgs_enctypes: 23 18 17. >>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType >>> CksumType: sun.security.krb5.internal.crypto.HmacMd5ArcFourCksumType >>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType getKDCFromDNS using UDP >>> KrbKdcReq send: kdc=server2016.forestgump.internal. TCP:88, timeout=30000, number of retries =3, #bytes=1622 >>> KDCCommunication: kdc=server2016.forestgump.internal. TCP:88, timeout=30000,Attempt =1, #bytes=1622 >>>DEBUG: TCPClient reading 1598 bytes >>> KrbKdcReq send: #bytes read=1598 >>> KdcAccessibility: remove server2016.forestgump.internal.:88 >>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType >>> KrbApReq: APOptions are 00100000 00000000 00000000 00000000 >>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType Krb5Context setting mySeqNumber to: 905416011 Created InitSecContextToken: 0000: 01 00 6E 82 05 DF 30 82 05 DB A0 03 02 01 05 A1 ..n...0......... ..... 05D0: BE 28 08 00 6F FC 45 DC 0D 90 93 E9 60 46 CC 81 .(..o.E.....`F.. 05E0: 51 D8 99 06 16 Q.... Entered Krb5Context.initSecContext with state=STATE_IN_PROCESS >>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType Krb5Context setting peerSeqNumber to: 1474518462 [Krb5LoginModule]: Entering logout [Krb5LoginModule]: logged out Subject
和用户帐户(tomcat和mario)都支持Kerberos 128/256位加密。
无法查明配置错误
我正在尝试使用Kerberos在Tomcat 9(使用SDK 8)中配置SSO。我的环境全部在Windows Server 2016 VM中:-server2016.forestgump.internal 192.168.44.130-Active Directory ...
问题似乎出在您的ksetup /setenctypeattr FQDN>forestgump.internal RC4-HMAC-MD5 AES128-CTS-HMAC-SHA1-96 AES256-CTS-HMAC-SHA1-96
中的分号: