I'm configuring WS-Security for my web service with Apache CXF. I've added WSS4JInInterceptor
and callback and it's working. The problem is that some methods don't require to be protected by WS-Security and some should.
How can i do that way? Any annotations or input map keys for WSS4JInInterceptor?
I can see in WSS4jInInterceptor code:
public void handleMessage(SoapMessage msg) throws Fault {
if (msg.containsKey(SECURITY_PROCESSED) || isGET(msg)) {
return;
}
So it seems i can add my custom interceptor and add SECURITY_PROCESSED
to unprotected methods, but it seems that there is better approach.
For now i had to reinvent the wheel with my own Interceptor
impl:
// adds skip flag for methods that should not be checked
public static class CheckMethodsInterceptor implements PhaseInterceptor<SoapMessage> {
private List<String> checkedMethods;
public CheckMethodsInterceptor(List<String> checkedMethods) {
this.checkedMethods = checkedMethods;
}
protected void allowConnection(SoapMessage message) {
// skip checking by WSS4JInInterceptor
message.put(WSS4JInInterceptor.SECURITY_PROCESSED, "true");
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
String action = (String)message.get("SOAPAction");
if (action == null || !checkedMethods.contains(action.substring(action.lastIndexOf("/") + 1))) {
allowConnection(message);
}
}
@Override
public Set<String> getAfter() {
return Collections.emptySet();
}
@Override
public Set<String> getBefore() {
return Collections.emptySet();
}
@Override
public String getId() {
return CheckMethodsInterceptor.class.getName();
}
@Override
public String getPhase() {
return Phase.PRE_PROTOCOL;
}
@Override
public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() {
return null;
}
@Override
public void handleFault(SoapMessage message) {
}
}
and use it like this:
// checked methods only (before WSS4JInInterceptor !)
SecurityService.CheckMethodsInterceptor checkMethodsInterceptor =
new SecurityService.CheckMethodsInterceptor(Arrays.asList(
"CreateUsers",
"GetUsers"
));
ep.getServer().getEndpoint().getInInterceptors().add(checkMethodsInterceptor);
WSS4JInInterceptor inSecurityInterceptor = new WSS4JInInterceptor(inSecurityProperties);
Feel free to suggest better solution.