使用WSS4J 2.1.4进行Spring-WS 2.3.0安全标头验证 - NoSecurity不起作用

时间:2016-06-06 13:30:45

标签: spring-ws wss4j

我正在使用Spring-WS for Client尝试更新到最新版本。尽管配置为不验证传入的安全头,但新的Wss4jSecurityInterceptor会抛出Wss4jSecurityValidationException(“找不到WS-Security头”)。

<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor">
  <property name="securementActions" value="UsernameToken"/>
  <property name="validationActions" value="NoSecurity"/>
  <property name="securementPasswordType" value="PasswordText"/>
  <property name="securementUsernameTokenElements" value="Nonce"/>
</bean>

在我看来,这是因为Spring-WS 2.3.0和WSS4J 2.1.4在这一点上是不兼容的。

Wss4jSecurityInterceptor按如下方式填充字段validationActionsVector:

public void setValidationActions(String actions) {
  this.validationActions = actions;
  try {
    validationActionsVector = WSSecurityUtil.decodeAction(actions);
  }
  catch (WSSecurityException ex) {
    throw new IllegalArgumentException(ex);
  }
}

其中WSS4J在NoSecurity的情况下在WSSecurityUtil中返回一个空List:

public static List<Integer> decodeAction(String action) throws WSSecurityException {
    String actionToParse = action;
    if (actionToParse == null) {
        return Collections.emptyList();
    }
    actionToParse = actionToParse.trim();
    if ("".equals(actionToParse)) {
        return Collections.emptyList();
    }

    List<Integer> actions = new ArrayList<>();
    String single[] = actionToParse.split("\\s");
    for (int i = 0; i < single.length; i++) {
        if (single[i].equals(WSHandlerConstants.NO_SECURITY)) {
            return actions;
        } else if ...

但是Wss4jSecurityInterceptor检查列表中的NoSecurity-Item:

@Override
protected void validateMessage(SoapMessage soapMessage, MessageContext messageContext)
        throws WsSecurityValidationException {
    if (logger.isDebugEnabled()) {
        logger.debug("Validating message [" + soapMessage + "] with actions [" + validationActions + "]");
    }

    if (validationActionsVector.contains(WSConstants.NO_SECURITY)) {
        return;
    } ...

这是一个已知问题吗?是否存在变通方法?或者我是否必须覆盖WSS4J中的方法以使用预期项填充列表?

4 个答案:

答案 0 :(得分:2)

我遇到了同样的问题 - 无法避免验证 - 但我解决了这个问题:

在拦截器中将validateRequest和validateResponse设置为false

无需破解任何代码或扩展任何类。您可以在https://jira.spring.io/browse/SWS-961查看相关问题。

答案 1 :(得分:0)

我同意,这是一个问题。

我有相同的场景,我不需要验证传入的消息。

我在我的应用程序类中重写了validateMessage方法,该方法扩展了Wss4jSecurityInterceptor,这似乎是一个更清晰的解决方案。

@覆盖 protected void validateMessage(SoapMessage soapMessage,MessageContext messageContext)抛出WsSecurityValidationException {
返回;
}

答案 2 :(得分:0)

我发现了一个适合我的工作方式。当然,最好在下一个Spring-WS版本中修复。

public class MyWss4jSecurityInterceptor extends Wss4jSecurityInterceptor {

  private String validationActions;

  /**
   * Overrides the method in order to avoid a security check if the 
   * ValidationAction 'NoSecurity'is selected.
   *
   * @param messageContext
   */
  @Override
  protected void validateMessage(SoapMessage soapMessage, MessageContext messageContext)
        throws WsSecurityValidationException {
    if (!WSHandlerConstants.NO_SECURITY.equals(validationActions)) {
        super.validateMessage(soapMessage, messageContext);
    }
  }

  /**
   * @return the validationActions
   */
  public String getValidationActions() {
    return validationActions;
  }

  /**
   * @param validationActions the validationActions to set
   */
  @Override
  public void setValidationActions(String validationActions) {
    this.validationActions = validationActions;
    super.setValidationActions(validationActions);
  }
}

答案 3 :(得分:0)

可以使用"org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor“不推荐使用。

它对我有用,而不是创建新的类扩展,无论如何我没有使用它进行任何验证。