How to access username principle in a cxf-se with ws-security?
I finally got the Ws-Security working with CXF-BC & CXF-SE combination. I'm now trying to access the username from the soap header in the SE to check permission and ownership of the user calling a operation, but there seems to be no way of doing that. I know that once a message get passed from the BC to the SE, it just takes the SOAP body and wraps in a JBI msg. Is there anyway to stuff the soap header in the JBI msg or, have the BC truly forward the SOAP msg as it has received it. I've tried to disable the JBIwrapper on the BC and SE, while it sends the message as SOAP it only sends the body of the original msg san header.
I'm not sure why this is so har开发者_运维知识库d and complex to do this on the BC/SE, since it was relatively easy to do with JAXWS.
Thanks
This answer came from Freeman over at the Servicemix-user mailing-list.
Basically you have to set a JBI property on a BC's ininterceptor, and then you can access it over on the SE.
ex. ininterceptor
public class SaveSubjectInterceptor extends AbstractPhaseInterceptor {
public SaveSubjectInterceptor() {
super(Phase.PRE_INVOKE);
}
public void handleMessage(Message message) throws Fault {
List<Object> results = (List<Object>) message.get(WSHandlerConstants.RECV_RESULTS);
if (results == null) {
return;
}
for (Iterator iter = results.iterator(); iter.hasNext();) {
WSHandlerResult hr = (WSHandlerResult) iter.next();
if (hr == null || hr.getResults() == null) {
return;
}
boolean authenticated = false;
for (Iterator it = hr.getResults().iterator(); it.hasNext();) {
WSSecurityEngineResult er = (WSSecurityEngineResult) it.next();
Object wstockPrincipal = er.get(WSSecurityEngineResult.TAG_PRINCIPAL);
if (er != null && wstockPrincipal instanceof WSUsernameTokenPrincipal) {
WSUsernameTokenPrincipal p = (WSUsernameTokenPrincipal) wstockPrincipal;
NormalizedMessage nm = (NormalizedMessage) message.getContent(NormalizedMessage.class);
nm.setProperty("Username", p.getName());
break;
}
}
}
}
}
ex of SE pojo
@Resource
private WebServiceContext wsContext;
...
...
javax.xml.ws.handler.MessageContext ctx = wsContext.getMessageContext();
org.apache.cxf.message.Message message = ((org.apache.cxf.jaxws.context.WrappedMessageContext) ctx).getWrappedMessage();
String username = (String) message.get("Username");
I hope this helps someone else.
I have a full example here w/ ws-security policy, but it is only there for a limited amount of time.
精彩评论