我正在尝试与 CXF 的 WS 安全实现(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 WSS4J 项目的 .processor.UsernameTokenProcessor#handleUsernameToken() 方法 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 的设计允许我这样做,因为我可以手动加密它。是否有任何方法可以在回调中设置加密密码或对存储的加密密码进行 usernametoken 身份验证?
我正在使用cxf 2.5.x
答案(我已经尝试过)可以在此博客页面中找到:
http://coheigea.blogspot.com/2011/06/custom-token-validation-in-apache-cxf.html
本质是创建org.apache.ws.security.validate.UsernameTokenValidator的子类,并重写verifyPlaintextPassword方法。 在该方法中,传递 UsernameToken(提供 getName 和 getPassword)。 如果它们无效,则抛出异常。
要在 Spring 配置中安装自定义验证器,请添加例如
<jaxws:properties>
<entry key="ws-security.ut.validator">
<bean class="com.example.webservice.MyCustomUsernameTokenValidator" />
</entry>
</jaxws:properties>
进入
回调处理程序用于提供明文密码或验证明文密码已知的摘要密码。
但是如果您不知道明文,即它的单向哈希值,那么回调接口就不合适,您应该创建一个实现 Validator 接口的类。
这是我对该接口的示例实现,它使用 JPA 存储库,其中密码已存储为 BCrypt 哈希。
与
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);
}
}
有没有办法使用java而不是xml来配置ws-security.ut.validator?