Mar*_*cak 5 java kerberos jetty active-directory spnego
我似乎无法正确配置系统并让浏览器向网络服务器发送kerberos票证。相反,NTLM会发送一个令牌。
问:我该如何解决这个问题?
下面列出了所有详细信息和配置。
基础设施:
我在域内有三台机器COMPANY.local:
PC-I7.COMPANY.local(在192.168.0.5)。它的作用是KDC,它是一个Active-Directory服务器,其他机器(见下文)在 AD 中注册。还DNS配置了本地网络。Active Directory 中的域是:COMPANY.localSOFTWARE.COMPANY.local(上192.168.0.10)运行Jetty/SPNego。OTHER.COMPANY.local(在192.168.0.9),只是一个客户端,这样我就可以从另一台机器访问软件服务器。最后两个实际上是在内网的服务器VM上运行的。linux他们可以通过自己的 IP 进行访问。他们的主要DNS观点Network Configuration是192.168.0.5。
两者都加入COMPANY.local并作为计算机存在于AD.
我知道客户端和服务器应该位于不同的机器上;将它们放在两个不同的VM' 上应该可以避免这个问题。
所有三台机器都在 中注册为A主机,DNS并在 中为每台机器都有一个反向指针Reverse lookup zone。
SPN
在 Active Directory 中创建用户后software,我生成 keytab 文件
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
Run Code Online (Sandbox Code Playgroud)
我得到以下输出,其中似乎包含错误:
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)
Run Code Online (Sandbox Code Playgroud)
用户选中AD了两个This account supports the Kerbers AES-...复选框。
服务器OTHER.COMPANY.local
我通过RDP以下凭据登录到这台机器:
user: Administrator
pass: ARandomPass
Run Code Online (Sandbox Code Playgroud)
OTHER当向服务器索取票证时
kinit HTTP/software.company.local@COMPANY.LOCAL
Run Code Online (Sandbox Code Playgroud)
我可以看到这个数据包wireshark
Internet Explorer(以及 Chrome)在 中具有以下设置Internet Options:
Security > Local Intranet > Sites > *.company.local
Security > Custom level > Automatic logon only in Intranet area
Run Code Online (Sandbox Code Playgroud)
当我到达网络应用程序时http://software.company.local:8998/software/login
我可以看到浏览器发送了一个NTLM请求
我可以在服务器端看到有缺陷的令牌异常
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)
Run Code Online (Sandbox Code Playgroud)
此信息也出现在java日志中:
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
Run Code Online (Sandbox Code Playgroud)
我可以从链接的答案中收集信息:
第 1 点:HTTP 服务的 SPN 与浏览器输入的 URL 确实匹配。我software.company.local在浏览器中输入与SPN相同的HTTP/software.company.local@COMPANY.LOCAL
第2点:*.company.local添加到受信任站点。
第 3 点:我不会将加密限制为DES-CBC-MD5
第 3 点:我已经检查过AES-128并且AES-256...但不是DES因为我正在使用的 Windows Server 版本有复选框显示Use only Kerberos DES encryption types for this account,这不是我想要的。我应该检查一下吗?
服务器SOFTWARE.COMPANY.local
这
码头Web 应用程序注册为 Windows Server。
这些是配置文件:
krb5.ini文件:
[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
}
Run Code Online (Sandbox Code Playgroud)
spnego.conf文件:
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;
};
Run Code Online (Sandbox Code Playgroud)
这是spnego.properties文件:
targetName = HTTP/software.company.local
Run Code Online (Sandbox Code Playgroud)
我的jetty-web.xml配置文件包含:
<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>
Run Code Online (Sandbox Code Playgroud)
这是我以编程方式注册spnego配置的方式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;
}
Run Code Online (Sandbox Code Playgroud)
和
// here I disable the TRACE method for all calls
Handler wrappedSecurityHandler = wrapDisableTraceHandlers(handlers);
wrappedSecurityHandler = wrapEnableSSOAuthHandlers(wrappedSecurityHandler);
_server.setHandler(wrappedSecurityHandler);
Run Code Online (Sandbox Code Playgroud)
编辑 1:附加信息
我已经下载了Kerberos 身份验证测试工具KDC,当从服务器 ( )运行它192.168.0.5并对其进行测试时http://software.company.local:8998,显示了正确的Kerberos身份验证。
当从192.168.0.10服务器(浏览器所在的位置)运行它时,它会显示:
意外的授权标头
和验证方法:NTLM。
我想这要么是一个问题,要么是它们在同一服务器上的DNS两个事实。VM
显然,在两个不同的虚拟机(位于同一物理服务器上!)上拥有客户端和服务器可以产生NTLM令牌。
我认为VM这会避免同一台机器上的客户端和服务器问题。
所以,如果你
VM驻留在同一台物理机器上的进行测试,并且Defective token detected,您应该尝试从另一台计算机访问server(只要该计算机已加入公司域)。
| 归档时间: |
|
| 查看次数: |
8099 次 |
| 最近记录: |