【发布时间】:2014-02-16 11:40:53
【问题描述】:
我实现了 LDAP 身份验证。我需要同时支持 TLS 和 SSL。
我使用以下代码:
Properties bindEnv = new Properties();
LdapContext bindCtx = null;
....
if (SSL){
bindEnv.put(Context.PROVIDER_URL, "ldaps://ldap.example.com:636");
}
else{
if(TLS){
bindEnv.put(Context.PROVIDER_URL, "ldap://ldap.example.com:389");
}
}
bindEnv.put(Context.SECURITY_PRINCIPAL, "INITIAL DN");
bindEnv.put(Context.SECURITY_CREDENTIALS, "PASSWORD");
bindCtx = new InitialLdapContext(bindEnv, null);
if(TLS){
StartTlsResponse tls =
(StartTlsResponse) bindCtx.extendedOperation(new StartTlsRequest());
tls.negotiate();
}
... Get username/password and authenticate user...
现在,在 SSL 模式下,初始 DN 和密码通过 SSL 发送。如果出现问题,初始上下文会立即抛出异常。
但在 TLS 模式下,密码是通过普通的 389 端口发送的。 TLS 仅在之后开始。
那么,TLS 是什么意思呢?它不安全。
似乎在TLS的情况下,正确的方法是打开没有DN/密码的初始上下文,启动TLS,然后使用绑定/重新连接?
类似:
if (SSL){
bindEnv.put(Context.PROVIDER_URL, "ldaps://ldap.example.com:636");
bindEnv.put(Context.SECURITY_PRINCIPAL, "INITIAL DN");
bindEnv.put(Context.SECURITY_CREDENTIALS, "PASSWORD");
bindCtx = new InitialLdapContext(bindEnv, null);
}
else{
if(TLS){
bindEnv.put(Context.PROVIDER_URL, "ldap://ldap.example.com:389");
bindCtx = new InitialLdapContext(bindEnv, null);
StartTlsResponse tls =
(StartTlsResponse) bindCtx.extendedOperation(new StartTlsRequest());
tls.negotiate();
bindCtx.addToEnvironment(Context.SECURITY_PRINCIPAL, "INITIAL DN");
bindCtx.addToEnvironment(Context.SECURITY_CREDENTIALS,"PASSWORD");
bindCtx.reconnect(null);
}
}
这是确保初始密码始终安全发送的方法吗?
谢谢
【问题讨论】:
-
首先问问自己,为什么SSL和TLS使用不同的端口以及不同的“SSL”和“TLS”是什么意思,因为SSL和TLS是同一个东西(同一个协议的不同版本)。所以不清楚,你在做什么以及为什么。
-
我使用不同的 LDAP 服务器。如果我只使用 SSL,这意味着我强制所有客户的 LDAP 服务器监听安全端口(例如 636),而在 TLS 中他们也可以使用 389 端口。
-
好吧,您需要阅读一些有关 SSL/TLS 的内容,然后细化您的问题(如果问题仍然存在)。到目前为止,您似乎在谈论隐式和显式模式,在这种情况下,所描述的行为是完全正确的。
-
您混淆了 TLS,它是 SSL 协议的更高版本,与 STARTTLS, 是 LDAP 和其他协议中的一个选项,用于将明文连接升级到 TLS .您正在寻找的是 STARTTLS。