2016-09-07 20 views
16

Đang cố gắng để di chuyển một ứng dụng từ WebLogic 12.2.1 để Tomcat 8.5.4, những gì thuộc WebLogic là một mục như cung cấp JNDI Ngoại cho kết nối LDAP đã được di chuyển sang một số mới Resource dưới Tomcat.Tomcat 8 - LDAP: NameNotFoundException mã lỗi 32, tên còn lại trống rỗng chuỗi

Sau this advice trên Ngăn xếp ngăn xếp, một tùy chỉnh LdapContextFactory đã được đóng gói dưới dạng tệp jar mới trong thư mục Tomcat lib.

Trong Tomcat server.xml file GlobalNamingResources/Resource sau đã được cấu hình:

<Resource name="ldapConnection" 
     auth="Container" 
     type="javax.naming.ldap.LdapContext" 
     factory="com.sample.custom.LdapContextFactory" 
     singleton="false" 
     java.naming.referral="follow" 
     java.naming.factory.initial="com.sun.jndi.ldap.LdapCtxFactory" 
     java.naming.provider.url="ldap://some.host:389" 
     java.naming.security.authentication="simple" 
     java.naming.security.principal="CN=some,OU=some,OU=some,DC=some,DC=a,DC=b" 
     java.naming.security.credentials="password" 
     com.sun.jndi.ldap.connect.pool="true" 
     com.sun.jndi.ldap.connect.pool.maxsize="10" 
     com.sun.jndi.ldap.connect.pool.prefsize="4" 
     com.sun.jndi.ldap.connect.pool.timeout="30000" /> 

Kết nối trên hoạt động tốt khi duyệt thư mục LDAP thông qua một trình duyệt LDAP như Apache Directory Studio/Trình duyệt LDAP nhúng trong Eclipse.

Tục com.sample.custom.LdapContextFactory là khá đơn giản:

public class LdapContextFactory implements ObjectFactory { 

    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) 
      throws Exception { 

     Hashtable<Object, Object> env = new Hashtable<>(); 
     Reference reference = (Reference) obj; 
     Enumeration<RefAddr> references = reference.getAll(); 

     while (references.hasMoreElements()) { 
      RefAddr address = references.nextElement(); 
      String type = address.getType(); 
      String content = (String) address.getContent(); 
      env.put(type, content); 
     } 
     return new InitialLdapContext(env, null); 
    } 
} 

Tuy nhiên, lúc khởi động Tomcat được ném ngoại lệ sau đây:

07-Sep-2016 15:04:01.064 SEVERE [main] org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans Exception processing Global JNDI Resources 
javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031001E5, problem 2001 (NO_OBJECT), data 0, best match of: 
    '' 
]; remaining name '' 
    at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3160) 
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3081) 
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2888) 
    at com.sun.jndi.ldap.LdapCtx.c_listBindings(LdapCtx.java:1189) 
    at com.sun.jndi.toolkit.ctx.ComponentContext.p_listBindings(ComponentContext.java:592) 
    at com.sun.jndi.toolkit.ctx.PartialCompositeContext.listBindings(PartialCompositeContext.java:330) 
    at com.sun.jndi.toolkit.ctx.PartialCompositeContext.listBindings(PartialCompositeContext.java:317) 
    at javax.naming.InitialContext.listBindings(InitialContext.java:472) 
    at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:136) 
    at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:145) 
    at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:110) 
    at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:82) 
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94) 
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:401) 
    at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:345) 
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:784) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152) 
    at org.apache.catalina.startup.Catalina.start(Catalina.java:655) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:355) 
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:495) 

Similar câu hỏi và điều tra đề nghị một hợp lệ LDAP DN, nhưng:

  • Cùng một cấu hình LDAP hoạt động tốt qua L DAP Khách hàng
  • Không tìm kiếm được thực sự thực hiện, lúc khởi động Tomcat ném ngoại lệ này mà không cần bất kỳ truy vấn
  • Các lỗi cho thấy một chuỗi rỗng '' như remaining name, do đó không thực sự không tìm thấy một cái gì đó, rõ ràng

Câu hỏi: Đây có phải là cách chính xác để di chuyển Nhà cung cấp JNDI Nước ngoài mục nhập từ WebLogic đến Tomcat? Cách khắc phục mục nhập DN LDAP không hợp lệ bằng tên còn lại trống? Có thể thiếu baseDN để định cấu hình ở đâu đó không?


Cập nhật
Các lỗi chính xác tương tự xảy ra khi thay đổi LdapContextFactory đến những điều sau đây, theo đề nghị thông qua ý kiến:

public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) 
     throws Exception { 

    Hashtable<Object, Object> env = new Hashtable<>(); 
    Reference reference = (Reference) obj; 
    Enumeration<RefAddr> references = reference.getAll(); 

    String providerUrl = "no valid URL"; 

    while (references.hasMoreElements()) { 
     RefAddr address = references.nextElement(); 
     String type = address.getType(); 
     String content = (String) address.getContent(); 

     switch (type) { 
     case Context.PROVIDER_URL: 
      env.put(Context.PROVIDER_URL, content); 
      providerUrl = content; 
      break; 

     default: 
      env.put(type, content); 
      break; 
     } 
    } 

    InitialLdapContext context = null; 
    Object result = null; 
    try { 
     context = new InitialLdapContext(env, null); 

     LOGGER.info("looking up for " + providerUrl); 
     result = context.lookup(providerUrl); 
    } finally { 
     if (context != null) { 
      context.close(); 
     } 
    } 
    LOGGER.info("Created new LDAP Context"); 
    return result; 
} 

Thay đổi được xác nhận thông qua khai thác gỗ, để chắc chắn rằng nó đã được triển khai đúng .

Người nghe có liên quan được xác định theo mặc định ở trên cùng của tập tin server.xml như

<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> 

Và không thể bị vô hiệu theo official documentation:

Các Tài Toàn Cầu Vòng đời Listener khởi nguồn lực toàn cầu JNDI được xác định trong server.xml như một phần của phần tử Tài nguyên toàn cầu. Nếu không có người nghe này, sẽ không có Tài nguyên toàn cầu nào khả dụng.


Quy định này cũng xảy ra trên phiên bản Tomcat 8.5.57.0.69: chỉ cần thêm các nguồn lực toàn cầu mới như trên và jar thêm cung cấp các nhà máy trên, ngoại trừ chỉ vào một tên còn lại trống sẽ được ném.

+1

Tôi không biết tại sao nó gọi 'listBindings()'. Nhà máy ngữ cảnh LDAP của tôi trả về 'iniitalLdapContext.lookup (url);' trong đó 'url' là URL của nhà cung cấp, và đóng' InitialLdapContext' trong một khối 'cuối cùng'. . – EJP

+1

@EJP thực sự tìm kiếm [ở đây] (https://svn.apache.org/repos/asf/tomcat/trunk/java/org/apache/catalina/mbeans/GlobalResourcesLifecycleListener.java), trong khi tạo mbean, nó gọi một 'listBindings 'với một chuỗi rỗng, đó có lẽ là nguyên nhân của vấn đề. Sau đó tôi sẽ vô hiệu hóa mbean cho 'Tài nguyên' này (hoặc cho tất cả), nhưng tôi không thể tìm thấy cách thực hiện nó –

+0

Hãy thử nó theo cách của tôi với tra cứu. – EJP

Trả lời

2

Stacktrace biến mất bằng cách thêm vào thuộc tính java.naming.provider.url lược đồ LDAP DN, sử dụng triển khai nhà máy đầu tiên được cung cấp trong câu hỏi.

Bên dưới ảnh chụp màn hình của ứng dụng khách LDAP được sử dụng trong ngữ cảnh này, Trình duyệt thư mục Apache/Studio Apache được nhúng trong Eclipse, từ đó có thể duyệt LDAP liên quan chỉ đơn giản bằng cách sử dụng các giá trị ban đầu của câu hỏi.

enter image description here

By phụ schema DN của phần tử gốc đến URL kết nối, ngoại trừ đi xa và tài nguyên LDAP bây giờ được chia sẻ qua JNDI trong Tomcat 8.


Thông tin chi tiết như kết quả của việc khắc phục sự cố:

Trong Tomcat 8 tài nguyên toàn cầu được xử lý thông qua trình nghe tài nguyên toàn cầu, GlobalResourcesLifecycleListener, được xác định bởi defa trong tập tin server.xml. Một người nghe như vậy invokes a context.listBindings("") về tạo bean, do đó có hiệu quả duyệt thư mục LDAP. Lần duyệt đầu tiên này có thể là sự khác biệt giữa Tomcat và WebLogic, trong đó LDAP được tra cứu thông qua JNDI chỉ khi được yêu cầu, do đó thông qua truy vấn trực tiếp, thay vì khởi động với truy vấn chung. Như vậy, trong Tomcat, url LDAP sẽ cần thêm chi tiết, tức là, một cấu hình hơi khác một phần trong url của nó để trỏ trực tiếp đến DN cơ sở hợp lệ.

Từ chính thức WebLogic documentation:

On khởi động, WebLogic Server cố gắng kết nối với nguồn JNDI. Nếu kết nối thành công, WebLogic Server sẽ thiết lập các đối tượng và liên kết được yêu cầu trong cây JNDI cục bộ, làm cho chúng có sẵn cho các máy khách WebLogic Server.

Do đó, một kết nối khá đơn giản hơn một listBindings:

liệt kê những cái tên bị ràng buộc trong bối cảnh đặt tên, cùng với các đối tượng bị ràng buộc đối với họ. Nội dung của bất kỳ phụ lục nào không được bao gồm.

Các vấn đề liên quan