Java Webstart 信任库 SSL
需要一些指导。
我有 java webstart 应用程序,我希望它通过 SSL 连接到服务器。只需添加一个属性,例如:System.setProperty("javax.net.ssl.trustStore","my.keystore");但是由于 JAWS 程序是从服务器下载的文件不起作用,并且本地文件系统上没有 my.keystore。因此决定将证书分发给所有客户。我执行了以下操作并且成功了。
- 将此信任存储作为流读取(使用 getResourceAsStream 方法)。
- 将其保存在客户端计算机上的任何文件中(sometemp)
- Call System.setProperty ("javax.net.ssl.trustStore", trustStorePath);
但我确信一定有比这更好的解决方案。有什么想法可以让它变得更好吗?
public boolean validateUserFromActiveDirectory(String userId) {
final String MEMBER_GROUP = "CN=asdadasd,OU=asdasdasd Accounts,OU=adasdas,OU=asdasdas,DC=asdasdas,DC=asdasdas,DC=adasdasd,DC=asdasdasd";
String employeeNumber = "";
final String LDAP_INIT_CTX = "com.sun.jndi.ldap.LdapCtxFactory";
final String LDAP_URL = "ldap://xx-ssssssss.eee.eee.eeeee.eeeee:636";
final String MY_ATTRS[] = { "employeeNumber" };
String adminPassword = "somepassword";
String securityProtocol = "ssl";
boolean isValidUser = false;
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_INIT_CTX);
env.put(Context.PROVIDER_URL, LDAP_URL);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.REFERRAL, "follow");
env.put(Context.SECURITY_PRINCIPAL, MEMBER_GROUP);
env.put(Context.SECURITY_CREDENTIALS, adminPassword);
env.put(Context.SECURITY_PROTOCOL, securityProtocol);
//C:\Documents and Settings\yourusername\Local Settings\Temp
File tf = File.createTempFile("someTruststore", ".jks");
tf.deleteOnExit();
byte buffer[] = new byte[0x1000];
ClassLoader cl = JNDI.class.getClassLoader();
InputStream in = cl.getResourceAsStream(
"someTruststore.jks");
FileOutputStream out = new FileOutputStream(tf);
int cnt;
while ((cnt = in.read(buffer)) != -1)
out.write(buffer, 0, cnt);
in.close();
out.close();
System.setProperty("javax.net.ssl.trustStore", tf
.getAbsolutePath());
DirContext context = new InitialLdapContext(env, null);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration results = context.search(
"XX=ent,XX=abc,XX=aaaaa,XX=aaaa", "(sAMAccountName="
+ userId + ")", searchControls);
if (results != null && results.hasMore()) {
//some logic
}
}
} catch (Exception e) {
e.printStackTrace();
}
return isValidUser;
}
-帕杜尔 ==========================================
/**
* */
package util;
/**
* @author spaduri
*
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
public class CustomSSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory factory;
public CustomSSLSocketFactory() {
try {
SSLContext sslcontext = null;
// Call getKeyManagers to get suitable key managers
KeyManager[] kms=getKeyManagers();
if (sslcontext == null) {
sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(kms,
new TrustManager[] { new CustomTrustManager() },
new java.security.SecureRandom());
}
factory = (SSLSocketFactory) sslcontext.getSocketFactory();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static SocketFactory getDefault() {
return new CustomSSLSocketFactory();
}
public Socket createSocket(Socket socket, String s, int i, boolean flag) throws IOException {
return factory.createSocket(socket, s, i, flag);
}
public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr1, int j) throws IOException {
return factory.createSocket(inaddr, i, inaddr1, j);
}
public Socket createSocket(InetAddress inaddr, int i) throws IOException {
return factory.createSocket(inaddr, i);
}
public Socket createSocket(String s, int i, InetAddress inaddr, int j) throws IOException {
return factory.createSocket(s, i, inaddr, j);
}
public Socket createSocket(String s, int i) throws IOException {
return factory.createSocket(s, i);
}
public String[] getDefaultCipherSuites() {
return factory.getSupportedCipherSuites();
}
public String[] getSupportedCipherSuites() {
return factory.getSupportedCipherSuites();
}
protected KeyManager[] getKeyManagers()
throws IOException, GeneralSecurityException
{
// First, get the default KeyManagerFactory.
String alg=KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg);
// Next, set up the KeyStore to use. We need to load the file into
// a KeyStore instance.
ClassLoader cl = CustomSSLSocketFactory.class.getClassLoader();
// read the file someTrustStore from the jar file from a classpath
InputStream in = cl.getResourceAsStream("ssl/someTruststore.jks");
//FileInputStream fis=new FileInputStream(adentTruststore.jks);
KeyStore ks=KeyStore.getInstance("jks");
ks.load(in, null);
in.close();
// Now we initialise the KeyManagerFactory with this KeyStore
kmFact.init(ks, null);
// And now get the KeyManagers
KeyManager[] kms=kmFact.getKeyManagers();
return kms;
}
}
package util;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class CustomTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] cert, String authType) {
return;
}
public void checkServerTrusted(X509Certificate[] cert, String authType) {
return;
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
Laz 感谢您的耐心,当我有时间时尝试学习。 我开始编写自己的 CustomSSLSocketFactory..现在我正在绕过安全性...基于白金解决方案的示例。如果我这样做...信息会以明文形式在网络上传递吗?
现在我想知道我应该如何处理我拥有“sometruststore.jks”文件的信任库文件。我该怎么办……我有编写自己的自定义信任管理器软件吗? 请引导我正确的方向。
-帕杜尔
Need some guidance.
I have java webstart app and I want it to connect to a server via SSL.just adding a property like:System.setProperty("javax.net.ssl.trustStore","my.keystore");But since a JAWS program is downloaded from server didn't work and don't have a my.keystore on local file system. So decided to distribute the certificate to all clients.I did the following and it worked.
- Read this trust store as a stream (use getResourceAsStream method).
- Save it in any file on the client machine (sometemp)
- Call System.setProperty ("javax.net.ssl.trustStore", trustStorePath);
But I am sure there must be better solutions than this.. Any ideas to make it better?
public boolean validateUserFromActiveDirectory(String userId) {
final String MEMBER_GROUP = "CN=asdadasd,OU=asdasdasd Accounts,OU=adasdas,OU=asdasdas,DC=asdasdas,DC=asdasdas,DC=adasdasd,DC=asdasdasd";
String employeeNumber = "";
final String LDAP_INIT_CTX = "com.sun.jndi.ldap.LdapCtxFactory";
final String LDAP_URL = "ldap://xx-ssssssss.eee.eee.eeeee.eeeee:636";
final String MY_ATTRS[] = { "employeeNumber" };
String adminPassword = "somepassword";
String securityProtocol = "ssl";
boolean isValidUser = false;
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_INIT_CTX);
env.put(Context.PROVIDER_URL, LDAP_URL);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.REFERRAL, "follow");
env.put(Context.SECURITY_PRINCIPAL, MEMBER_GROUP);
env.put(Context.SECURITY_CREDENTIALS, adminPassword);
env.put(Context.SECURITY_PROTOCOL, securityProtocol);
//C:\Documents and Settings\yourusername\Local Settings\Temp
File tf = File.createTempFile("someTruststore", ".jks");
tf.deleteOnExit();
byte buffer[] = new byte[0x1000];
ClassLoader cl = JNDI.class.getClassLoader();
InputStream in = cl.getResourceAsStream(
"someTruststore.jks");
FileOutputStream out = new FileOutputStream(tf);
int cnt;
while ((cnt = in.read(buffer)) != -1)
out.write(buffer, 0, cnt);
in.close();
out.close();
System.setProperty("javax.net.ssl.trustStore", tf
.getAbsolutePath());
DirContext context = new InitialLdapContext(env, null);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration results = context.search(
"XX=ent,XX=abc,XX=aaaaa,XX=aaaa", "(sAMAccountName="
+ userId + ")", searchControls);
if (results != null && results.hasMore()) {
//some logic
}
}
} catch (Exception e) {
e.printStackTrace();
}
return isValidUser;
}
-Padur
===========================**=============
/**
*
*/
package util;
/**
* @author spaduri
*
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
public class CustomSSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory factory;
public CustomSSLSocketFactory() {
try {
SSLContext sslcontext = null;
// Call getKeyManagers to get suitable key managers
KeyManager[] kms=getKeyManagers();
if (sslcontext == null) {
sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(kms,
new TrustManager[] { new CustomTrustManager() },
new java.security.SecureRandom());
}
factory = (SSLSocketFactory) sslcontext.getSocketFactory();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static SocketFactory getDefault() {
return new CustomSSLSocketFactory();
}
public Socket createSocket(Socket socket, String s, int i, boolean flag) throws IOException {
return factory.createSocket(socket, s, i, flag);
}
public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr1, int j) throws IOException {
return factory.createSocket(inaddr, i, inaddr1, j);
}
public Socket createSocket(InetAddress inaddr, int i) throws IOException {
return factory.createSocket(inaddr, i);
}
public Socket createSocket(String s, int i, InetAddress inaddr, int j) throws IOException {
return factory.createSocket(s, i, inaddr, j);
}
public Socket createSocket(String s, int i) throws IOException {
return factory.createSocket(s, i);
}
public String[] getDefaultCipherSuites() {
return factory.getSupportedCipherSuites();
}
public String[] getSupportedCipherSuites() {
return factory.getSupportedCipherSuites();
}
protected KeyManager[] getKeyManagers()
throws IOException, GeneralSecurityException
{
// First, get the default KeyManagerFactory.
String alg=KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg);
// Next, set up the KeyStore to use. We need to load the file into
// a KeyStore instance.
ClassLoader cl = CustomSSLSocketFactory.class.getClassLoader();
// read the file someTrustStore from the jar file from a classpath
InputStream in = cl.getResourceAsStream("ssl/someTruststore.jks");
//FileInputStream fis=new FileInputStream(adentTruststore.jks);
KeyStore ks=KeyStore.getInstance("jks");
ks.load(in, null);
in.close();
// Now we initialise the KeyManagerFactory with this KeyStore
kmFact.init(ks, null);
// And now get the KeyManagers
KeyManager[] kms=kmFact.getKeyManagers();
return kms;
}
}
package util;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class CustomTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] cert, String authType) {
return;
}
public void checkServerTrusted(X509Certificate[] cert, String authType) {
return;
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
Laz appreciate your patience, trying to learn when I get some time.
I started writing my own CustomSSLSocketFactory..right now I am bypassing security...based on the example by platinum solutions.If I do that ...will the information pass as a clear text on the network?
Now I wonder what should I do with the truststore file I am having "sometruststore.jks" file. What should I do with that ..Do I have wrie my own custom trustmanager software ?
Please guide me in correct direction.
-padur
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您无需依赖系统属性和文件系统即可完成此操作。像您正在做的那样将密钥库作为流读取并创建您自己的 SSLSocketFactory 会更干净。
我还没有验证,但我认为没有理由不能通过 Webstart 来实现。
更新:
您提到您正在寻求连接到 Active Directory,所以我猜您将使用 LDAPS 作为协议?如果是这样,也许 此 URL 处的代码可以作为灵感?您必须创建
javax.net.ssl.SSLSocketFactory
(请参阅 Platinumsolutions 链接中的BlindSSLSocketFactoryTest
),它包装了上面创建 SSLContext 的逻辑 并将调用委托给context.getSocketFactory()
创建的SSLSocketFactory
。希望能够编译,我现在无法测试它!另请注意
initTrustedSSLSocketFactory
上的throws
子句的惰性。然后,当您设置 LDAP 环境时,请
按照与 Platinumsolutions 中的示例代码类似的方式使用。希望这正是您所寻找的?
You could do it without having to rely on system properties and the file system. Reading the keystore as a stream like you are doing and creating your own SSLSocketFactory would be much cleaner.
I haven't verified but I see no reason why this shouldn't work through Webstart.
Updated:
You mention that you are looking to connect to active directory so I'm guessing you are going to use LDAPS as the protocol? If so, maybe the code at this URL can serve as inspiration? You'll have to create a subclass of
javax.net.ssl.SSLSocketFactory
(seeBlindSSLSocketFactoryTest
at that platinumsolutions link) that wraps the logic above of creating the theSSLContext
and delegates calls to theSSLSocketFactory
thatcontext.getSocketFactory()
creates.Hopefully that compiles, I'm unable to test it at the moment! Also note the laziness with the
throws
clause oninitTrustedSSLSocketFactory
.Then when you setup the LDAP environment, use
in a similar manner to the sample code at platinumsolutions. Hopefully this is more of what you're looking for?