Ich versuche, einen "Java First" Webservice zu erstellen, der einfache und einfache UsernameToken WS-Security verwendet. Ich habe versucht, den Beispielen von CXF zu folgen. Wenn ich meine WSDL abfrage, sehe ich keine Erwähnung von irgendetwas, was mit der Sicherheit zusammenhängt. Ich benutze CXF 2.7.5 und versuche alles mit Anmerkungen zu machen.UsernameToken WS-Security mit Apache CXF Anmerkungen (WSS4J)
Das Folgende ist meine gescheiterte Versuch:
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 Abhängigkeiten:
<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>
ich nicht eine Sache bekommt, warum brauchen Sie Passworld® Anrufabwicklung auf der Client-Seite zu implementieren. Der Kunde sollte sich keine Sorgen machen müssen. Wie würde es funktionieren, wenn der Client PHP oder .NET wäre ??? – Makky