Windows 事件查看器 - Kerberos 登录后立即注销
Windows Event Viewer - Kerberos logon followed immediately by a logoff
我正在尝试实施集成在基于 jetty 的应用程序中的 Kerberos 身份验证系统。
从我的机器请求一张带有 kinit HTTP/app.company.local@COMPANY.LOCAL
的票证后,我在 Chrome
上打开网页,我得到了堆栈跟踪:
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.ssl.SslConnection.onFillable(SslConnection.java:201)
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.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.run(QueuedThreadPool.java:589)
at java.lang.Thread.run(Thread.java:748)
我可以找到一些关于这个问题的线索(尽管 none 到目前为止对我有用)。我猜服务器 returns 一个 Web 应用程序无法解析的 NTLM
令牌。
不过我可以评估,鉴于事件日志,Web 应用程序确实设法到达了 Kerberos 服务器:
我想知道为什么 注销 会发生,如果它改变了身份验证结果,从而触发网络服务器上的 GSSException
。
- 前两个条目(在
Log clear
之后)、Logon
和 Special Logon
事件具有登录 ID:0xCDE977CB
.
- 另外两个 +
Logoff
事件的 ID:0xCDE9781A
.
*.company.local
和 *.company.com
(localhost 网络服务器 URL)已添加到 Intranet 受信任站点(我不太明白我必须信任哪个站点)
- 我正在通过 VPN 连接到 Kerberos 服务器
- 我必须将 Jetty/SPNego 类 与我们自定义的本地身份验证系统绑定
问题出自 GSSHeader.class
,如堆栈跟踪所示。
出于某种原因,我得到了错误的代码。
我的配置文件:
spnego.conf
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
principal = "HTTP/app.company.local"
keyTab = "D:/00_company/workspace/branch_develop/modules/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/app.company.local"
useKeyTab = true
keyTab = "D:/00_company/workspace/branch_develop/modules/config/auth/krb5.keytab"
storeKey=true
debug=true
isInitiator=false;
};
krb5.ini
[libdefaults]
default_realm = COMPANY.LOCAL
permitted_enctypes = aes256-cts arcfour-hmac-md5 aes256-cts-hmac-sha1-96
default_tgs_enctypes = aes128-cts aes256-cts arcfour-hmac-md5 aes256-cts-hmac-sha1-96
default_tkt_enctypes = aes128-cts aes256-cts arcfour-hmac-md5 aes256-cts-hmac-sha1-96
default_keytab_name = D:/00_company/workspace/branch_develop/modules/common-config/auth/krb5.keytab
default_cache_name = C:/Users/mp91/krb5cc_mp91
[realms]
COMPANY.LOCAL = {
kdc = PC-i7.COMPANY.local:88
admin_server = 192.168.0.5
default_domain = company.local
}
[domain_realm]
company.local = COMPANY.LOCAL
.company.local = COMPANY.LOCAL
[appdefaults]
autologin = true
forwardable = true
spnego.properties
targetName = HTTP/app.company.local
这是在应用程序启动时以编程方式注册 <security-constraint>
的 Java
代码。
private SecurityHandler wrapEnableSSOAuthHandlers(final Handler collection) {
// programmaticaly set JVM properties
// ini file
System.setProperty(
"java.security.krb5.conf",
_config.getString("authentication.win_sso.spnego.krb5")
);
System.setProperty(
"java.security.auth.login.config",
_config.getString("authentication.win_sso.spnego.login")
);
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.DOMAIN"
spnegoConstraint.setRoles(new String[]{domainRealm});
spnegoConstraint.setAuthenticate(true);
final ConstraintMapping mapping = new ConstraintMapping();
mapping.setConstraint(spnegoConstraint);
mapping.setPathSpec("/*");
final SpnegoLoginService loginService = new SpnegoLoginService();
final String spnegoProperties = _config.getString("authentication.win_sso.spnego.properties");
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;
}
报名:
// ...
Handler wrappedSecurityHandler = wrapDisableTraceHandlers(handlers);
final boolean enableWinSSOauthentication = _config.getBoolean("authentication.win_sso.enable");
if (enableWinSSOauthentication) {
wrappedSecurityHandler = wrapEnableSSOAuthHandlers(wrappedSecurityHandler);
}
_server.setHandler(wrappedSecurityHandler);
// ...
这个(在我的例子中)的解决方案与我发布的 相同。
基本上(引用我的回答):
having client and server on two distinct virtual machines ( that are on the same physical server! ) can lead to a NTLM
token.
So, if you 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).
我正在尝试实施集成在基于
从我的机器请求一张带有 kinit HTTP/app.company.local@COMPANY.LOCAL
的票证后,我在 Chrome
上打开网页,我得到了堆栈跟踪:
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.ssl.SslConnection.onFillable(SslConnection.java:201)
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.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.run(QueuedThreadPool.java:589)
at java.lang.Thread.run(Thread.java:748)
我可以找到一些关于这个问题的线索(尽管 none 到目前为止对我有用)。我猜服务器 returns 一个 Web 应用程序无法解析的 NTLM
令牌。
不过我可以评估,鉴于事件日志,Web 应用程序确实设法到达了 Kerberos 服务器:
我想知道为什么 注销 会发生,如果它改变了身份验证结果,从而触发网络服务器上的 GSSException
。
- 前两个条目(在
Log clear
之后)、Logon
和Special Logon
事件具有登录 ID:0xCDE977CB
. - 另外两个 +
Logoff
事件的 ID:0xCDE9781A
. *.company.local
和*.company.com
(localhost 网络服务器 URL)已添加到 Intranet 受信任站点(我不太明白我必须信任哪个站点)- 我正在通过 VPN 连接到 Kerberos 服务器
- 我必须将 Jetty/SPNego 类 与我们自定义的本地身份验证系统绑定
问题出自 GSSHeader.class
,如堆栈跟踪所示。
出于某种原因,我得到了错误的代码。
我的配置文件:
spnego.conf
com.sun.security.jgss.initiate {
com.sun.security.auth.module.Krb5LoginModule required
principal = "HTTP/app.company.local"
keyTab = "D:/00_company/workspace/branch_develop/modules/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/app.company.local"
useKeyTab = true
keyTab = "D:/00_company/workspace/branch_develop/modules/config/auth/krb5.keytab"
storeKey=true
debug=true
isInitiator=false;
};
krb5.ini
[libdefaults]
default_realm = COMPANY.LOCAL
permitted_enctypes = aes256-cts arcfour-hmac-md5 aes256-cts-hmac-sha1-96
default_tgs_enctypes = aes128-cts aes256-cts arcfour-hmac-md5 aes256-cts-hmac-sha1-96
default_tkt_enctypes = aes128-cts aes256-cts arcfour-hmac-md5 aes256-cts-hmac-sha1-96
default_keytab_name = D:/00_company/workspace/branch_develop/modules/common-config/auth/krb5.keytab
default_cache_name = C:/Users/mp91/krb5cc_mp91
[realms]
COMPANY.LOCAL = {
kdc = PC-i7.COMPANY.local:88
admin_server = 192.168.0.5
default_domain = company.local
}
[domain_realm]
company.local = COMPANY.LOCAL
.company.local = COMPANY.LOCAL
[appdefaults]
autologin = true
forwardable = true
spnego.properties
targetName = HTTP/app.company.local
这是在应用程序启动时以编程方式注册 <security-constraint>
的 Java
代码。
private SecurityHandler wrapEnableSSOAuthHandlers(final Handler collection) {
// programmaticaly set JVM properties
// ini file
System.setProperty(
"java.security.krb5.conf",
_config.getString("authentication.win_sso.spnego.krb5")
);
System.setProperty(
"java.security.auth.login.config",
_config.getString("authentication.win_sso.spnego.login")
);
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.DOMAIN"
spnegoConstraint.setRoles(new String[]{domainRealm});
spnegoConstraint.setAuthenticate(true);
final ConstraintMapping mapping = new ConstraintMapping();
mapping.setConstraint(spnegoConstraint);
mapping.setPathSpec("/*");
final SpnegoLoginService loginService = new SpnegoLoginService();
final String spnegoProperties = _config.getString("authentication.win_sso.spnego.properties");
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;
}
报名:
// ...
Handler wrappedSecurityHandler = wrapDisableTraceHandlers(handlers);
final boolean enableWinSSOauthentication = _config.getBoolean("authentication.win_sso.enable");
if (enableWinSSOauthentication) {
wrappedSecurityHandler = wrapEnableSSOAuthHandlers(wrappedSecurityHandler);
}
_server.setHandler(wrappedSecurityHandler);
// ...
这个(在我的例子中)的解决方案与我发布的
基本上(引用我的回答):
having client and server on two distinct virtual machines ( that are on the same physical server! ) can lead to a
NTLM
token.So, if you 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).