使用java web修改AD域用户密码报错解决方案

报错如下
javax.naming.CommunicationException: simple bind failed: 服务器地址:636 [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]


javax.naming.CommunicationException: simple bind failed: 服务器地址:636 [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
*****Start search *******'s distinguishedName
五月 13, 2019 9:50:17 上午 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet [springmvc] in context with path [/ITrepair] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
	at com.sw.service.PasswordServiceImpl.searchDistinguishedName(PasswordServiceImpl.java:80)
	at com.sw.service.PasswordServiceImpl.chpwd(PasswordServiceImpl.java:142)
	at com.sw.controller.PasswordController.changePwd(PasswordController.java:89)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Unknown Source)

网上看到有相同的错误但是找了好久没找到解决方法,都是在本地application不报错,web访问报错
在本地把方法写到main方法跑是没有问题的 正常连接 正常改密
项目是开发的企业微信项目
在调用企业微信接口(获得个人信息)后,填写新密码,点击修改密码(调用项目中的业务层的连接AD域方法)则报错。
但是如果直接浏览器地址访问控制层调用业务层的方法 则不报错,如果不重启tomcat,之后从微信端也可以正常连接AD域 搞不懂什么情况23333
然后我就在代码中加了启动tomcat执行连接AD域的方法 之后从微信端访问则可正常连接AD域不报错
解决问题代码如下:
web.xml代码:


          com.sw.sendtest.LdapTest  

启动tomcat执行方法:

public class LdapTest implements ServletContextListener {
		//开启tomcat执行方法  配合web.xml监听器食用
		@Override
		public void contextDestroyed(ServletContextEvent arg0) {
			// TODO Auto-generated method stub
		}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		// TODO Auto-generated method stub
		 System.out.println("tomcat启动");
		 PasswordServiceImpl psi=new PasswordServiceImpl();
		 psi.initialLdap();
		 psi.closeLdap();
	}
}

连接/关闭AD域代码:

public boolean initialLdap() {
		Hashtable env = new Hashtable();
		System.setProperty("javax.net.ssl.trustStore", keystore);
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.SECURITY_PRINCIPAL, "域账号");
		env.put(Context.SECURITY_CREDENTIALS, "密码");
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
		env.put(Context.SECURITY_PROTOCOL, "ssl");
		env.put(Context.PROVIDER_URL, "ldaps://服务器地址");
		try {
			System.out.println("*****开始初始化Ldap");
			ctx = new InitialLdapContext(env, null);
			System.out.println("*****初始化Ldap成功");
		} catch (NamingException e) {
			System.out.println("初始化Ldap出现问题" + e);
			return false;
		}
		return true;
}
public boolean closeLdap() {
		System.out.println("*****关闭 Ldap");
		try {
			ctx.close();
		} catch (NamingException e) {
			System.out.println("关闭Ldap出现问题  NamingException: " + e);
			return false;
		}
		return true;
	}

PS:只贴了执行方法的代码,没有把定义的变量内容贴出,请结合实际修改应用
然后就会每次启动tomcat先成功连接一次AD域,之后web端访问也可以正常连接
虽然不明白是什么原理 但是还是暂时解决了这个问题23333
如果大佬们有更好的解决办法,欢迎分享~

你可能感兴趣的:(AD域)