CXF的WS-security(usernametoken) - 加密密码可能吗?

时间:2012-01-19 12:02:02

标签: cxf ws-security usernametoken

我正在努力与CXF的WS-security实现(usernametoken)结合在一起。我按照http://cxf.apache.org/docs/ws-security.html所说的完成了所有事情。我的PasswordCallbackHandler似乎正在工作,但困扰我的是一部分:

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

如上所述

  

请注意,对于最高版本和包括CXF 2.3.x,明文密码(或任何其他未知密码类型)的特殊情况的密码验证将委托给回调类,请参阅org.apache.ws .security.processor.UsernameTokenProcessor#handleUsernameToken()方法WSS4J项目的javadoc。在这种情况下,ServerPasswordCallback应该类似于以下内容:

所以cxf 2.3.x就是这样做的

   if (pc.getIdentifer().equals("joe") {
       if (!pc.getPassword().equals("password")) {
            throw new IOException("wrong password");
       }
    }

我的问题是:我不想pc.setPassword(“plainTextPassword”),因为我想将它存储在任何资源中。这种高达2.3.x的设计允许我这样做,因为我可以手动加密它。有没有办法在回调中设置加密密码或对存储的加密密码进行用户名口令验证?

我正在使用cxf 2.5.x

2 个答案:

答案 0 :(得分:6)

答案(我已经尝试过)可以在这个博客页面中找到:

http://coheigea.blogspot.com/2011/06/custom-token-validation-in-apache-cxf.html

本质是创建org.apache.ws.security.validate.UsernameTokenValidator的子类,并覆盖verifyPlaintextPassword方法。在该方法中,传递UsernameToken(提供getName和getPassword)。如果它们无效则抛出异常。

要在弹簧配置中安装自定义验证器,请添加例如

  <jaxws:properties>
    <entry key="ws-security.ut.validator">
        <bean class="com.example.webservice.MyCustomUsernameTokenValidator" />
    </entry>
  </jaxws:properties>

进入&lt; jaxws:endpoint /&gt;。

答案 1 :(得分:2)

回调处理程序用于提供明文密码或验证明文密码已知的摘要密码。

但是如果你不知道明文,即它的单向散列,那么回调接口是不合适的,你应该创建一个实现Validator接口的类。

这是我使用JPA存储库的接口的示例实现,其中密码已经存储为BCrypt哈希。

与记录在案here

ws-security.ut.validator属性一起使用

即。作为CXF财产 <entry key="ws-security.ut.validator" value-ref="com.package.CustomUsernameTokenValidator" />

public class CustomUsernameTokenValidator implements Validator {
    @Autowired
    ProfileRepository profileRepository;
    @Override
    public Credential validate(Credential credential, RequestData requestData) throws WSSecurityException {
        Profile profile = profileRepository.findByName(credential.getUsernametoken().getName());
        if (profile != null) {
            if (BCrypt.checkpw(credential.getUsernametoken().getPassword(), profile.getPassword())) {
                return credential;
            }
        }
        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);     
    }
}