Spring security 3.0.x + LDAP pres SSL za pouziti certifikatu

el.wondris na centrum.cz el.wondris na centrum.cz
Pondělí Listopad 29 13:11:13 CET 2010


V konfiguraku nic takoveho neni . Pouze nejaky DefaultSpringContextSource...

<!-- CONFIGURATION FOR ACTIVE DIRECTORY AUTH. -->
	<!-- **************************************** -->

	<bean id="springSecurityAuthenticationSource" class="org.springframework.security.ldap.authentication.SpringSecurityAuthenticationSource" />
	
	<bean id="authenticationSource" class="org.springframework.ldap.authentication.DefaultValuesAuthenticationSourceDecorator">
		<property name="target" ref="springSecurityAuthenticationSource" />
		<property name="defaultUser" value="${ac.default.domain}${ac.default.username}" />
		<property name="defaultPassword" value="${ac.default.password}" />
	</bean>
	
        <bean id="securityContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
		<constructor-arg value="${ac.protocol}://${ac.server.ip}:${ac.server.port}" />
		<property name="authenticationSource" ref="authenticationSource"/>
		<property name="baseEnvironmentProperties">
			<map>
				<entry key="com.sun.jndi.ldap.connect.timeout" value="${ac.connection.timeout}" />
			</map>
		</property>
	</bean>
	
	<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
		<constructor-arg index="0">
			<value>${ac.path.users}</value>
		</constructor-arg>
		<constructor-arg index="1">
			<value>sAMAccountName={0}</value>
		</constructor-arg>
		<constructor-arg index="2">
			<ref local="securityContextSource" />
		</constructor-arg>
		<property name="searchSubtree" value="true" />
	</bean>
	
	<bean id="bindAuthenticator" class="org.springframework.security.ldap.authentication.BindAuthenticator">
		<constructor-arg>
			<ref local="securityContextSource"/>
		</constructor-arg>
		<property name="userSearch" ref="userSearch" />
	</bean>
	
	<bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
		<constructor-arg index="0">
			<ref local="securityContextSource" />
		</constructor-arg>
		<constructor-arg index="1">
			<value>${ac.path.groups}</value>
		</constructor-arg>
		<property name="searchSubtree" value="true"/>
	</bean>
	
	
	<bean id="userDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
		<constructor-arg index="0">
			<ref local="userSearch" />
		</constructor-arg>
		<constructor-arg index="1">
			<ref local="ldapAuthoritiesPopulator" />
		</constructor-arg>
	</bean>
	
	
	<bean id="authenticationProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
		<constructor-arg index="0">
			<ref local="bindAuthenticator" />
		</constructor-arg>
		<constructor-arg index="1">
			<ref local="ldapAuthoritiesPopulator" />
		</constructor-arg>
	</bean>
	
	<s:authentication-manager alias="authenticationManager">
		<s:authentication-provider ref="authenticationProvider" user-service-ref="userDetailsService" />
	</s:authentication-manager>

Nechapu, jak to mam nakonfigurat do toho XML? Pouzivam Spring security 3.0.x.

Lukas

______________________________________________________________
> Od: "Martin Kuba" <makub na ics.muni.cz>
> Komu: Java <konference na java.cz>
> 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 makub na 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 {
>             return factory.createSocket();
>         }
>
>         public Socket createSocket(String s, int i) throws IOException {
>             return factory.createSocket(s, i);
>         }
>
>         public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException {
>             return factory.createSocket(s, i, inetAddress, i1);
>         }
>
>         public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
>             return factory.createSocket(inetAddress, i);
>         }
>
>         public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
>             return factory.createSocket(inetAddress, i, inetAddress1, i1);
>         }
>     }
>}
>
>
>Klientský certifikát pak musí být ve formátu JKS nebo PKCS12 v souboru
>odkazovaném property keyStoreFile a v property keyStorePassword
>musí být heslo k soouboru i ke klíči, to u PKCS12 bývá totožné.
>
>Tož tak.
>
>Makub
>-- 
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>Supercomputing Center Brno             Martin Kuba
>Institute of Computer Science    email: makub na ics.muni.cz
>Masaryk University             http://www.ics.muni.cz/~makub/
>Botanicka 68a, 60200 Brno, CZ     mobil: +420-603-533775
>--------------------------------------------------------------
>


Další informace o konferenci Konference