Ubuntu下的LDAP的搭建与Spring LDAP编程

最近要装LDAP.
不得不感叹wiki.ubuntu.org.cn真是非常的强大,要啥有啥。
按照上面的步骤,OpenLDAP Server就很快搭好了,
自动搜索到了我的本地域名,
设置admin密码
如丝般柔顺。。。
(其实也不尽然,我家的服务器按照上面的步骤,竟然没有最重要的slapd.conf,
郁闷死我了)
 
然后就是找一个Administrator
网上的资源纷繁复杂,让我找了好半天
对LDAP的完全不了解-,-,主要是对Dn,Cn的混淆,
让我尝试了很多客户端都放弃了。。。。
(其实Dn=Base+Cn,皑皑,后来才知道)
最后选择了phpldapadmin,简洁,明了,
主要是在网上搜到了可以直接设置cn,,,
第一个让我登录成功的Administrator….感动了
sudo apt-get install phpldapadmin
 
稍微玩了一把LDAP
感觉就是针对公司机构,人事特别设计的一颗对象树。
Root就是Base Domain
地下可以设置人员CN,机构OU和其他各种对象。
Email Account,User Account,一应俱全。
最主要的是还可以自己Customize,复选多种objectclass来订制节点属性。
其实用处不大,可能主要是已经应用非常广泛了吧。
 
OK,玩好了最大的用处当然是集成到我的应用中。
用过了Spring以后就难以割舍,集成太方便了,inject就有了。
Java Main写的Demo Code可以很方便的intergrate到其他web application中。
所以Spring LDAP当然就是我的不二选择。
 
说实话Spring LDAP非常的贴心,
就怕你不会用,基本的用法完全类似JDBCTemplate(当然还有Triditional的用法,没来得及看)
三下五除二就搞定了(当然除了可怕的dn,cn)….
public class UserDaoLdapImpl {
    private LdapTemplate ldapTemplate;
    public LdapTemplate getLdapTemplate() {
        return ldapTemplate;
    }
    public void setLdapTemplate(LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
    }
    public List GetAllPersonNames(){
        return this.ldapTemplate.search("","(&(objectclass=person)(cn=*ny*))",
                new AttributesMapper(){
                    public Object mapFromAttributes(Attributes attrs)
                        throws NamingException{
                        return attrs.get("cn").get();
                    }
        });
    }
}
<beans>
    <bean id="contextSource"
        class="org.springframework.ldap.core.support.LdapContextSource">
        <property name="url" value="ldap://XXXX:389" />
        <property name="base" value="dc=xiluo2,dc=com" />
        <property name="userDn" value="cn=admin,dc=xiluo2,dc=com" />
        <property name="password" value="xiuxiu" />
    </bean>
    <bean id="ldapTemplate"
        class="org.springframework.ldap.core.LdapTemplate">
        <constructor-arg ref="contextSource" />
    </bean>
    <bean id="userDao" class="hellospringldap.UserDaoLdapImpl">
        <property name="ldapTemplate">
            <ref bean="ldapTemplate" />
        </property>
    </bean>
</beans>
 
这里还要赞美以下Netbeans
直接建立Web Application就可以支持Spring, Hibernate(虽然没用上)
然后方便的添加Spring LDAP的Jar和beans申明,OK,搞定了。
 
最后就是LDAP和Call Manager的intergration.
1)System->LDAP System,选择类型OpenLDAP
2)System->LDAP Directory,设置Base,IP,port,Username,password(注意cn,dn…)
OK,搞定,Corporation Directory就可以用了。
 

 

一次Spring Refactoring实战

用CXF作了一个调用AXL Web Services的Demo,
现在需要把它放到我的Web Application里面,最快的方法当然是Spring Inject.
于是很bt的try了一把spring Refactoring.
 
说起来其实CXF本身对Spring的支持就非常的好。
基于Spring扩展的cxf.xml,基于Spring的FactoryBean和Client.
可要命的是AXL的Web Services并不标准。
一个定制HTTP认证头的Interceptor,一个定制的TrustManager,把美观的cxf.xml弄得一无是处。
加上之前CXF菜鸟,只是照葫芦画瓢,这些因为都导致了这次refactoring的艰辛。。。(-,-,铺陈铺陈)
 
原始的Code

public class AXLClient
   public static void main(String[] args) throws Exception {
        URL wsdlUrl = AXLClient.class.getResource("AXLAPI.wsdl");
        QName SERVICE_NAME = new QName("http://www.cisco.com/AXLAPIService/", "AXLAPIService");
        Service service = Service.create(wsdlUrl, SERVICE_NAME);
        AXLPort port = service.getPort(AXLPort.class);
        BindingProvider provider = (BindingProvider) port;
        Map<String, Object> reqContext = provider.getRequestContext();
        reqContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://IPAddress:8443/axl/");
        Client client = ClientProxy.getClient(port);
        client.getOutInterceptors().add(new AXLInterceptor());
        //set SSL
        HTTPConduit http = (HTTPConduit) client.getConduit();
        TLSClientParameters  tls = new TLSClientParameters();
        tls.setDisableCNCheck(true);
        tls.setTrustManagers(new TrustManager[]{new MyTrustManager()});
        http.setTlsClientParameters(tls);
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setAllowChunking(false);
        http.setClient(httpClientPolicy);
        GetPhoneReq req = new GetPhoneReq();
        req.setPhoneName("SEPXXXXXXXXX");
        System.out.println(port.getPhone(req));
    }
}

step 1
将"SEPXXXXXXXXX"替换为String ID
将public static void main() 修改为public voice getPhone(String ID);
然后Spring就可以注入了
<bean id="AXLClient" class="…"/>
娃哈哈,最后技术含量的就是这步了。。。
 
step 2
Spring的真髓就是IoC,"No new,All is injected"
于是有了这样四个Attributes
 private AbstractPhaseInterceptor<Message> authInterceptor;
 private TrustManager[] trustManagers;
 private Resource axlWsdl;
 private AXLPort axlPort;
 <bean id="axlService" class="com.cisco.twitter.axl.AXLServiceImpl">
  <property name="axlPort" ref="axlPort"/>
  <property name="axlWsdl"  value="classpath:AXLAPI.wsdl"/>
  <property name="authInterceptor"  ref="authInterceptor"/>
  <property name="trustManagers" >
   <list>
    <bean id="defaultTrustManager" class="com.cisco.twitter.axl.DefaultTrustManager"/>
   </list>
  </constructor-arg>
 </bean>
其中需要提到的是Spring的Resource真的很好用,直接classpath:XXX就可以调用我需要的资源文件了,方便一个字。
 
Step 3
其实这步应该水到渠成的。
CXF本来就支持Spring的配置集成。形如:
<bean id="axlPort" class="com.cisco.twitter.axl.model.AXLPort"
   factory-bean="axlClientFactory" factory-method="create"/>
   
 <bean id="axlClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
   <property name="serviceClass" value="com.cisco.twitter.axl.model.AXLPort"/>
   <property name="address" value="https://100.100.3.71:8443/axl/"/>
 </bean>
通过JaxWsProxyFactoryBean这个工厂类,可以方便的生成Client类。
可是由于我一开始的实现是胡乱拼凑的,所以根本不知道这里Factory,Client最硬的是我Code中的哪个部分。
所以绕了很多弯路。
最后发现“Client client = ClientProxy.getClient(port);”以上的code都可以通过上面的Code取代。
 
Step5
//set SSL
HTTPConduit http = (HTTPConduit) client.getConduit();

TLSClientParameters  tls = new TLSClientParameters();
tls.setDisableCNCheck(true);
tls.setTrustManagers(new TrustManager[]{new MyTrustManager()});
http.setTlsClientParameters(tls);
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
 
Spring中的实例默认是Singleton的。
以上的Code是对Request的定制,只需要执行一次就可以了。
于是可以把这段code放在构造函数中。
相应的修改是把Spring配置中的property修改成constructor-arg
因为构造函数需要其中的属性。
 
Step6
建立接口,好习惯,要保持。
public interface AXLService {
 public String getDeviceIdByPhoneNumber(String phoneNumber);
}
 
最后的结果

public interface AXLService {
 /**
  *
  * @param phoneNumber
  * @return
  */
 public String getDeviceIdByPhoneNumber(String phoneNumber);
}
public class AXLServiceImpl implements AXLService {
 private AbstractPhaseInterceptor<Message> authInterceptor;
 private TrustManager[] trustManagers;
 private Resource axlWsdl;
 private AXLPort axlPort;
    protected final Log log = LogFactory.getLog(getClass());
 
 public AXLServiceImpl(AXLPort axlPort,Resource axlWsdl,
   AbstractPhaseInterceptor<Message> authInterceptor,
   TrustManager[] trustManagers){
  this.axlPort = axlPort;
  this.axlWsdl = axlWsdl;
  this.authInterceptor = authInterceptor;
  this.trustManagers = trustManagers;
  
  Client client = ClientProxy.getClient(axlPort);
        //set the auth string
        client.getOutInterceptors().add(this.authInterceptor);
        //set the own trustManager
        HTTPConduit http = (HTTPConduit) client.getConduit();
        TLSClientParameters  tls = new TLSClientParameters();
        tls.setDisableCNCheck(true);
        tls.setTrustManagers(this.trustManagers);
        http.setTlsClientParameters(tls);
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        //set the content-length
        httpClientPolicy.setAllowChunking(false);
        http.setClient(httpClientPolicy);
  
 }
    /**
     * @param args the command line arguments
     */
    public String getDeviceIdByPhoneNumber (String phoneNumber) {
        ExecuteSQLQueryReq req = new ExecuteSQLQueryReq();
        req.setSql("select d.name from device d,devicenumplanmap m, numplan n "+
          "where d.pkid = m.fkdevice and m.fknumplan=n.pkid and n.dnorpattern=’"+
          phoneNumber+"’");
        try{
         ExecuteSQLQueryRes result = axlPort.executeSQLQuery(req);
         //the only user of the line
         if (result.getReturn().getRow().size() == 1 ){
          return ((Row)result.getReturn().getRow().get(0)).getName();
         }
         return null;
        }
        catch(SOAPFaultException e){
         log.warn("Failed to connect Call Manager." + e);
         return null;
        }
    }
}
<bean id="authInterceptor" class="com.cisco.twitter.axl.AuthInterceptor">
  <property name="ccmuser" value="ccmadmin"/>
  <property name="password" value="ipcbuadmin"/>
 </bean>
 <bean id="axlPort" class="com.cisco.twitter.axl.model.AXLPort"
   factory-bean="axlClientFactory" factory-method="create"/>
   
 <bean id="axlClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
   <property name="serviceClass" value="com.cisco.twitter.axl.model.AXLPort"/>
   <property name="address" value="https://XXXX:8443/axl/"/>
 </bean>
 
 <bean id="axlService" class="com.cisco.twitter.axl.AXLServiceImpl">
  <constructor-arg index="0" ref="axlPort"/>
  <constructor-arg index="1" value="classpath:AXLAPI.wsdl"/>
  <constructor-arg index="2" ref="authInterceptor"/>
  <constructor-arg index="3">
   <list>
    <bean id="defaultTrustManager" class="com.cisco.twitter.axl.DefaultTrustManager"/>
   </list>
  </constructor-arg>
 </bean>


 

 

无觅相关文章插件,快速提升流量