1

我终于让 Ws-Security 与 CXF-BC 和 CXF-SE 组合一起工作。我现在正在尝试从 SE 中的 soap 标头访问用户名,以检查调用操作的用户的权限和所有权,但似乎没有办法做到这一点。我知道一旦消息从 BC 传递到 SE,它只需要 SOAP 主体并包装在 JBI msg 中。无论如何要在 JBI 消息中填充肥皂标题,或者让 BC 在收到 SOAP 消息时真正转发它。我尝试在 BC 和 SE 上禁用 JBIwrapper,虽然它以 SOAP 形式发送消息,但它只发送原始 msg san 标头的正文。

我不确定为什么在 BC/SE 上这样做如此困难和复杂,因为使用 JAXWS 相对容易。

谢谢

4

1 回答 1

0

这个答案来自 Freeman 在 Servicemix-user 邮件列表。

基本上你必须在 BC 的 ininterceptor 上设置一个 JBI 属性,然后你可以在 SE 上访问它。

前任。拦截器

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;
            }
        }
    }
}

} 

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"); 

我希望这对其他人有帮助。
我在这里有一个带有 ws-security 策略的完整示例,但它只存在有限的时间。

于 2010-06-30T03:10:54.137 回答