Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu
Ahoj Javisti. Potreboval bych poradit s problemem, kdy je potreba se autentizovat/autorizovat LDAPem pres SSL za pouziti certifikatu pomoci Spring security. Od zakaznika jsem dostal certifikaty, ktere mam pouzit. Vubec netusim, jak a hlavne kam se ty certifikaty musi nacpat(JDK, Tomcat,...??), aby se pri autentizaci ty certifikaty pouzili. Muzete mi nekdo poradit? Popripade hodit nejaky link s prikladem. Predem dik, Lukas
Re: Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu
Pokud se jedná o serverový certifikát tak ten se pomocí keytool dá do JKS keystoru a cesta k tomu jks se nastaví jako truststoreFile u konektoru tomcata v server.xml. On 11/25/2010 05:58 PM, el.wond...@centrum.cz wrote: Ahoj Javisti. Potreboval bych poradit s problemem, kdy je potreba se autentizovat/autorizovat LDAPem pres SSL za pouziti certifikatu pomoci Spring security. Od zakaznika jsem dostal certifikaty, ktere mam pouzit. Vubec netusim, jak a hlavne kam se ty certifikaty musi nacpat(JDK, Tomcat,...??), aby se pri autentizaci ty certifikaty pouzili. Muzete mi nekdo poradit? Popripade hodit nejaky link s prikladem. Predem dik, Lukas
Re: Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu
Dne 25.11.2010 17:58, el.wond...@centrum.cz napsal(a): Ahoj Javisti. Potreboval bych poradit s problemem, kdy je potreba se autentizovat/autorizovat LDAPem pres SSL za pouziti certifikatu pomoci Spring security. Od zakaznika jsem dostal certifikaty, ktere mam pouzit. Vubec netusim, jak a hlavne kam se ty certifikaty musi nacpat(JDK, Tomcat,...??), aby se pri autentizaci ty certifikaty pouzili. Muzete mi nekdo poradit? Popripade hodit nejaky link s prikladem. Předpokládám, že se tím myslí klientské SSL certifikáty pro přístup k LDAP serveru, vůči kterému se ověří username a heslo uživatele, tj. to co je popsáno na http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ldap.html#ldap-context-source a ne třeba klientský SSL certifikát v uživatelově browseru, to by byla úplně jiná pohádka. Spring Security jsem nepoužíval, jenom Spring LDAP, ale podle toho popisu soudím, že je třeba si vytvořit vlastní implementaci AbstractContextSource, viz http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/index.html?org/springframework/ldap/core/support/AbstractContextSource.html která se k připojí k LDAP serveru a použije přitom SSL certifikát. V něm je třeba se správně autentizovat, popis je na http://download.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html v části "Using Custom Sockets". Je třeba si vytvořit SslSocketFactory, která dokáže předložit klientský SSL certifikát. To se dělá zhruba takto: SSLContext sc = SSLContext.getInstance("SSL"); TrustManager[] myTrustManager = new TrustManager[]{ new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { //není potřeba u klienta } public void checkServerTrusted(X509Certificate[] certs, String authType) { //jen pokud chci ověřovat server } } }; KeyManager[] myKeyManager = new KeyManager[] { new X509KeyManager() { public String[] getClientAliases(String s, Principal[] principals) { } public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) { } public String[] getServerAliases(String s, Principal[] principals) { } public String chooseServerAlias(String s, Principal[] principals, Socket socket) { } public X509Certificate[] getCertificateChain(String s) { } public PrivateKey getPrivateKey(String s) { } } }; sc.init(myKeyManager, myTrustManager, new java.security.SecureRandom()); SSLSocketFactory sslSocketFactory = sc.getSocketFactory(); samozřejmě je třeba naimplementovat metody pro TrustManager a KeyManager tak, aby se ověřil saerver a předložil klientský SSL certifikát. Makub -- ~~ Supercomputing Center Brno Martin Kuba Institute of Computer Scienceemail: ma...@ics.muni.cz Masaryk University http://www.ics.muni.cz/~makub/ Botanicka 68a, 60200 Brno, CZ mobil: +420-603-533775 --
Re: Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu
Dne 26.11.2010 08:41, Martin Kuba napsal(a): Spring Security jsem nepoužíval, jenom Spring LDAP, ale podle toho popisu soudím, že je třeba si vytvořit vlastní implementaci AbstractContextSource, viz http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/index.html?org/springframework/ldap/core/support/AbstractContextSource.html která se k připojí k LDAP serveru a použije přitom SSL certifikát. V něm je třeba se správně autentizovat, popis je na http://download.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html v části "Using Custom Sockets". Je třeba si vytvořit SslSocketFactory, která dokáže předložit klientský SSL certifikát. To se dělá zhruba takto: Tak jsem si to zkusil, a je to tak. V konfiguraci Springu se musí org.springframework.ldap.core.support.LdapContextSource nahradit za vlastní implementaci, která musí vypadat nějak takto: package cz.makub; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ldap.core.support.AbstractContextSource; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.directory.DirContext; import javax.naming.ldap.InitialLdapContext; import javax.net.SocketFactory; import javax.net.ssl.*; import java.io.FileInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.URI; import java.net.URISyntaxException; import java.security.KeyStore; import java.util.Hashtable; /** * Alternative to LdapContextSource allowing client SSL certificates. * * @author Martin Kuba ma...@ics.muni.cz * @version $Id:$ * @see org.springframework.ldap.core.support.LdapContextSource */ public class MyContextSource extends AbstractContextSource { final static Logger log = LoggerFactory.getLogger(MyContextSource.class); private String keyStoreFile; private String keyStorePassword; public void setKeyStoreFile(String keyStoreFile) { this.keyStoreFile = keyStoreFile; } public void setKeyStorePassword(String keyStorePassword) { this.keyStorePassword = keyStorePassword; } @SuppressWarnings({"unchecked"}) @Override protected DirContext getDirContextInstance(Hashtable env) throws NamingException { String url = (String) env.get(Context.PROVIDER_URL); try { if (new URI(url).getScheme().equalsIgnoreCase("ldaps")) { env.put("java.naming.ldap.factory.socket", "cz.makub.MyContextSource$MySSLFactory"); MySSLFactory.setManagers(getKeyManagers(), null); } } catch (URISyntaxException e) { log.error("LDAP URL " + url + " is wrong", e); } return new InitialLdapContext(env, null); } private KeyManager[] getKeyManagers() { return getKeyManagers(loadKeyStoreFromFile(keyStoreFile, keyStorePassword), keyStorePassword); } private static KeyManager[] getKeyManagers(KeyStore keyStore, String storePassword) { try { KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); keyManagerFactory.init(keyStore, storePassword != null ? storePassword.toCharArray() : null); return keyManagerFactory.getKeyManagers(); } catch (Exception ex) { throw new RuntimeException(ex.getMessage(), ex); } } private static KeyStore loadKeyStoreFromFile(String ksfile, String password) { String kstype; if (ksfile.endsWith(".jks")) { kstype = "JKS"; } else if (ksfile.endsWith(".p12")) { kstype = "PKCS12"; } else { throw new RuntimeException("keystore file name " + ksfile + " must end with .ks (JKS) or .p12 (PKCS12)"); } try { KeyStore store = KeyStore.getInstance(kstype); store.load(new FileInputStream(ksfile), password != null ? password.toCharArray() : null); return store; } catch (Exception ex) { throw new RuntimeException(ex.getMessage(), ex); } } /** * SSL SocketFactory enabling client certificates and customs server checks. */ @SuppressWarnings({"UnusedDeclaration"}) public static class MySSLFactory extends SocketFactory { final static MySSLFactory thisFactory = new MySSLFactory(); static SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); public static void setManagers(KeyManager[] keyManagers, TrustManager[] trustManagers) { try { SSLContext sctx = SSLContext.getInstance("TLS"); sctx.init(keyManagers, trustManagers, null); factory = sctx.getSocketFactory(); } catch (Exception ex) { ex.printStackTrace(); } } public static SocketFactory getDefault() { return thisFactory; } @Override public Socket createSocket() throws IOException {
Re: Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu
V konfiguraku nic takoveho neni . Pouze nejaky DefaultSpringContextSource... ${ac.path.users} sAMAccountName={0} ${ac.path.groups} Nechapu, jak to mam nakonfigurat do toho XML? Pouzivam Spring security 3.0.x. Lukas __ > Od: "Martin Kuba" > Komu: Java > Datum: 26.11.2010 17:50 > Předmět: Re: Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu > >Dne 26.11.2010 08:41, Martin Kuba napsal(a): >> Spring Security jsem nepoužíval, jenom Spring LDAP, ale podle toho popisu >> soudím, >> že je třeba si vytvořit vlastní implementaci AbstractContextSource, viz >> http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/index.html?org/springframework/ldap/core/support/AbstractContextSource.html >> která se k připojí k LDAP serveru a použije přitom SSL certifikát. >> >> V něm je třeba se správně autentizovat, popis je na >> http://download.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html >> v části "Using Custom Sockets". Je třeba si vytvořit SslSocketFactory, která >> dokáže předložit klientský SSL certifikát. To se dělá zhruba takto: > >Tak jsem si to zkusil, a je to tak. V konfiguraci Springu se musí >org.springframework.ldap.core.support.LdapContextSource >nahradit za vlastní implementaci, která musí vypadat nějak takto: > >package cz.makub; > >import org.slf4j.Logger; >import org.slf4j.LoggerFactory; >import org.springframework.ldap.core.support.AbstractContextSource; > >import javax.naming.Context; >import javax.naming.NamingException; >import javax.naming.directory.DirContext; >import javax.naming.ldap.InitialLdapContext; >import javax.net.SocketFactory; >import javax.net.ssl.*; >import java.io.FileInputStream; >import java.io.IOException; >import java.net.InetAddress; >import java.net.Socket; >import java.net.URI; >import java.net.URISyntaxException; >import java.security.KeyStore; >import java.util.Hashtable; > >/** > * Alternative to LdapContextSource allowing client SSL certificates. > * > * @author Martin Kuba ma...@ics.muni.cz > * @version $Id:$ > * @see org.springframework.ldap.core.support.LdapContextSource > */ >public class MyContextSource extends AbstractContextSource { > > final static Logger log = LoggerFactory.getLogger(MyContextSource.class); > > private String keyStoreFile; > private String keyStorePassword; > > public void setKeyStoreFile(String keyStoreFile) { > this.keyStoreFile = keyStoreFile; > } > > public void setKeyStorePassword(String keyStorePassword) { > this.keyStorePassword = keyStorePassword; > } > > @SuppressWarnings({"unchecked"}) > @Override > protected DirContext getDirContextInstance(Hashtable env) throws > NamingException { > String url = (String) env.get(Context.PROVIDER_URL); > try { > if (new URI(url).getScheme().equalsIgnoreCase("ldaps")) { > env.put("java.naming.ldap.factory.socket", > "cz.makub.MyContextSource$MySSLFactory"); > MySSLFactory.setManagers(getKeyManagers(), null); > } > } catch (URISyntaxException e) { > log.error("LDAP URL " + url + " is wrong", e); > } > return new InitialLdapContext(env, null); > } > > private KeyManager[] getKeyManagers() { > return getKeyManagers(loadKeyStoreFromFile(keyStoreFile, > keyStorePassword), keyStorePassword); > } > > private static KeyManager[] getKeyManagers(KeyStore keyStore, String >
Re: Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu
Dne 29.11.2010 13:11, el.wond...@centrum.cz napsal(a): V konfiguraku nic takoveho neni . Pouze nejaky DefaultSpringContextSource... Tak právě ten bych zkusil vyměnit za ten můj MyContextSource. Oba jsou potomci AbstractContextSource http://static.springsource.org/spring-ldap/docs/1.3.x/apidocs/org/springframework/ldap/core/support/AbstractContextSource.html takže by měli být zaměnitelní. Pokud by to přesto nešlo, tak bych jako druhou možnost zkusil ten můj MyContextSource udělat jako potomka DefaultSpringContextSource místo AbstractContextSource, ve skutečnosti jde jenom o to předefinovat metodu getDirContextInstance() tak, aby podstrčila jako parametr vlastní implementaci SSLSocketFactory. Makub Od: "Martin Kuba" Komu: Java Datum: 26.11.2010 17:50 Předmět: Re: Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu Dne 26.11.2010 08:41, Martin Kuba napsal(a): package cz.makub; import org.springframework.ldap.core.support.AbstractContextSource; public class MyContextSource extends AbstractContextSource { -- ~~ Supercomputing Center Brno Martin Kuba Institute of Computer Scienceemail: ma...@ics.muni.cz Masaryk University http://www.ics.muni.cz/~makub/ Botanicka 68a, 60200 Brno, CZ mobil: +420-603-533775 --