java – 使用Apache CXF注释的UsernameToken WS-Security(WSS4J)
我正在尝试创建一个“
java first”webservice,它将使用简单的UsernameToken WS-Security.我试图遵循CXF的例子.当我查询我的wsdl时,我看不到任何与ws-security相关的内容.我正在使用CXF 2.7.5,我正在尝试用注释做所有事情.
以下是我失败的尝试: SampleService.java: import java.util.ArrayList; import java.util.Date; import javax.jws.WebParam; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import org.apache.cxf.annotations.EndpointProperties; import org.apache.cxf.annotations.EndpointProperty; @WebService(targetNamespace="https://test.company.com/ws/") @SOAPBinding(style = SOAPBinding.Style.RPC) @EndpointProperties({ @EndpointProperty(key = "action",value="UsernameToken"),@EndpointProperty(key = "passwordType",value="PasswordText"),@EndpointProperty(key = "ws-security.callback-handler",value="PasswordHandler"),//@EndpointProperty(key = "ws-security.validate.token",value="false"),}) public interface SampleService { @WebMethod public String getSample( @WebParam(name="startDate") Date startDate,@WebParam(name="endDate") Date endDate); } SampleServiceImpl.java: import java.util.Date; import javax.jws.WebMethod; import javax.jws.WebService; @WebService(endpointInterface = "SampleService",targetNamespace="https://test.company.com/ws/") public class SampleServiceImpl implements SampleService { @Override @WebMethod public String getSample(Date startDate,Date endDate) { StringBuilder sb = new StringBuilder(); sb.append("Start Date: "); sb.append(startDate.toString()); sb.append("n"); sb.append("End Date: "); sb.append(endDate.toString()); return sb.toString(); } } PasswordHandler.java: 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 PasswordHandler implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException,UnsupportedCallbackException { WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; System.out.println("User: " + pc.getIdentifier()); System.out.println("Password: " + pc.getIdentifier()); System.out.println("Type: " + pc.getType()); if (pc.getIdentifier().equals("joe")) { // set the password on the callback. This will be compared to the // password which was sent from the client. pc.setPassword("password"); } } } SampleServicePublisher.java: import java.util.HashMap; import java.util.Map; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.ws.security.WSConstants; import org.apache.ws.security.handler.WSHandlerConstants; public class SampleServicePublisher { public static void main(String[] args) { String URL = "http://localhost:9999/ws/SampleService"; EndpointImpl jaxWsEndpoint = (EndpointImpl) javax.xml.ws.Endpoint.publish(URL,new SampleServiceImpl()); Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint(); Map<String,Object> inProps= new HashMap<String,Object>(); // how to configure the properties is outlined below; WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps); cxfEndpoint.getInInterceptors().add(wssIn); Map<String,Object> outProps = new HashMap<String,Object>(); // how to configure the properties is outlined below; WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); cxfEndpoint.getOutInterceptors().add(wssOut); inProps.put(WSHandlerConstants.ACTION,WSHandlerConstants.USERNAME_TOKEN); // Password type : plain text inProps.put(WSHandlerConstants.PASSWORD_TYPE,WSConstants.PW_TEXT); // for hashed password use: //properties.put(WSHandlerConstants.PASSWORD_TYPE,WSConstants.PW_DIGEST); // Callback used to retrieve password for given user. inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,PasswordHandler.class.getName()); } } mvn依赖项: <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>2.7.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>2.7.5</version> </dependency> <!-- Jetty is needed if you're using the CXFServlet --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>2.7.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-rm</artifactId> <version>2.7.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-security</artifactId> <version>2.7.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-addr</artifactId> <version>2.7.5</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-policy</artifactId> <version>2.7.5</version> </dependency> </dependencies> 解决方法
您可以使用基于WS-SecurityPolicy的配置而不是WSS4J拦截器方法!
为此,从“java first”Web服务创建一个.wsdl文件,并使用和部分扩展它,并将其放在项目的任何位置. (f.e./ WEB-INF / wsdl) ... <binding name="SecurityServicePortBinding" type="tns:ServiceIface"> <wsp:PolicyReference URI="#SecurityServiceBindingPolicy"/> .... </binding> <service name="SecurityService"> <port name="SecurityServicePort" binding="tns:SecurityServicePortBinding"> <soap:address location="https://localhost:8443/jaxws-samples-wsse-policy-username"/> </port> </service> <wsp:Policy wsu:Id="SecurityServiceBindingPolicy"> <wsp:ExactlyOne> <wsp:All> <wsaw:UsingAddressing xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" wsp:Optional="true" /> <sp:TransportBinding> <wsp:Policy> <sp:TransportToken> <wsp:Policy> <sp:HttpsToken RequireClientCertificate="false" /> </wsp:Policy> </sp:TransportToken> <sp:Layout> <wsp:Policy> <sp:Lax /> </wsp:Policy> </sp:Layout> <sp:IncludeTimestamp/> <sp:AlgorithmSuite> <wsp:Policy> <sp:Basic128 /> </wsp:Policy> </sp:AlgorithmSuite> </wsp:Policy> </sp:TransportBinding> <sp:SignedSupportingTokens> <wsp:Policy> <sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:WssUsernameToken10 /> </wsp:Policy> </sp:UsernameToken> </wsp:Policy> </sp:SignedSupportingTokens> <sp:Wss11 /> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> </definitions> 在@Webservice批注中定义wsdlLocation参数,并使用@EndpointConfig批注而不是@EndpointProperties. @Stateless @WebService ( portName = "SecurityServicePort",serviceName = "SecurityService",wsdlLocation = "WEB-INF/wsdl/SecurityService.wsdl",targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wssecuritypolicy",endpointInterface = "org.jboss.test.ws.jaxws.samples.wsse.policy.wsdl.ServiceIface" ) @EndpointConfig(configFile = "WEB-INF/jaxws-endpoint-config.xml",configName = "Custom WS-Security Endpoint") public class ServiceImpl implements ServiceIface { public String sayHello() { return helloservice.sayHello(); } } 在WEB-INF / jaxws-endpoint-config.xml中定义ws-security.callback-handler. <?xml version="1.0" encoding="UTF-8"?> <jaxws-config xmlns="urn:jboss:jbossws-jaxws-config:4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="urn:jboss:jbossws-jaxws-config:4.0 schema/jbossws-jaxws-config_4_0.xsd"> <endpoint-config> <config-name>Custom WS-Security Endpoint</config-name> <property> <property-name>ws-security.callback-handler</property-name> <property-value>org.jboss.test.ws.jaxws.samples.wsse.policy.basic.UsernamePasswordCallback</property-value> </property> </endpoint-config> </jaxws-config> mvn依赖项: <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-security</artifactId> <version>${cxf.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.jboss.ws.native</groupId> <artifactId>jbossws-native-core</artifactId> <version>4.1.1.Final</version> <scope>provided</scope> </dependency> 加载org.apache.ws.security JBOSS模块: <?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure> <deployment> <dependencies> <module name="org.apache.ws.security"/> </dependencies> </deployment> </jboss-deployment-structure> 我实现了helloworld projekt:https://github.com/matyig/wsse-policy-username 如果您想使用非WS-SecurityPolicy方法,则可以使用spring xml配置方式.你在这里找到一个很好的教程: http://www.jroller.com/gmazza/entry/cxf_usernametoken_profile (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |