webService对外提供的服务,在验证客户端访问权限方面,最笨的验证方法应该是在业务方法上面加参数了,这也是之前的做法!发现网上通行的办法是在SOAP协议头增加对用户的验证。实验完总结如下。
?
客户端采用cxf+spring? 配置文件如下
?
<jaxws:endpoint id="receptionAdapter" implementor="#itReceptionAdapter" address="/resSync/ITReceptionAdapter"> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" /> <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" /> <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"> <constructor-arg> <map> <!-- --> <entry key="action" value="UsernameToken" /> <entry key="passwordType" value="PasswordText" /> <entry key="user" value="cxfServer" /> <entry key="passwordCallbackRef"> <ref bean="serverPasswordCallback" /> </entry> </map> </constructor-arg> </bean> </jaxws:inInterceptors> </jaxws:endpoint> <bean id="serverPasswordCallback" class="com.ServerPasswordCallback" />
?ServerPasswordCallback相当于filter,代码如下
import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class ServerPasswordCallback implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; String pw = pc.getPassword(); String idf = pc.getIdentifier(); System.out.println("密码是:" + pw); System.out.println("类型是:" + idf); if (pw.equals("test") && idf.equals("test")) { System.out.println("成功"); } else { throw new SecurityException("验证失败"); } } }
?
客户端采用axis2? 生成客户端代码访问
?
ITReceptionAdapterStub adapterStub=new ITReceptionAdapterStub(); //设置超时 adapterStub._getServiceClient().getOptions().setTimeOutInMilliSeconds(600000L); //设置header账号密码 ServiceClient serviceClient=adapterStub._getServiceClient(); SOAP11Factory factory=new SOAP11Factory(); OMNamespace SecurityElementNamespace = factory.createOMNamespace("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "wsse"); OMElement usernameTokenEl = factory.createOMElement("UsernameToken",SecurityElementNamespace); OMElement usernameEl = factory.createOMElement("Username",SecurityElementNamespace); OMElement passwordEl = factory.createOMElement("Password",SecurityElementNamespace); OMElement actionEl = factory.createOMElement("Action",SecurityElementNamespace); passwordEl.addAttribute(factory.createOMAttribute("Type",null,"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText")); usernameEl.setText("test"); passwordEl.setText("test"); usernameTokenEl.addChild(usernameEl); usernameTokenEl.addChild(passwordEl); usernameTokenEl.addChild(actionEl); SOAPHeaderBlockImpl block = new SOAP11HeaderBlockImpl("Security",SecurityElementNamespace, factory); block.addChild(usernameTokenEl); serviceClient.addHeader(block); ProcessE processE=new ProcessE(); Process process=new Process(); // process.setXmldata(); process.setXmldata(jiFangXml); process.setName("test"); process.setPassword("test"); processE.setProcess(process); ProcessResponseE responseE=adapterStub.process(processE); String xml=responseE.getProcessResponse().get_return(); System.out.println(xml);
?好了,这样既可做到在业务方法之外验证用户的权限,对外的业务方法里面也不会出现对权限的验证,不失为一种好办法 。
ps:网上的参考,加上自己经验,记录在此,备查