我有一个Spring-Boot项目,可以生成SOAP Web服务。我将其配置为使用WS-Security(Wss4jSecurityInterceptor)。使用JdbcUserDetailsManager从数据库(MySQL)加载用户。此外,我使用BCryptPasswordEncoder加密用户密码。
但是当我尝试使用Web服务时,我得到“安全令牌无法通过身份验证或授权;嵌套异常是org.apache.wss4j.common.ext.WSSecurityException:安全令牌无法通过身份验证或授权”。
我知道Spring-Boot正在尝试将纯文本密码与数据库中的加密密码进行比较。当我将密码保存在数据库中的纯文本时,它可以工作!
如何使用Spring-Boot在WS-Security上配置密码编码器?
Github项目:https://github.com/saenzemiliano/spring-boot-example-ws-wss.git
Web服务位置http://localhost:8080/sample/ws/countries
Web服务调用
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:gs="http://spring.io/guides/gs-producing-web-service">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soapenv:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="UsernameToken-D3BE54CA98BF76B3BF15548134030756">
<wsse:Username>admin</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">secret</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<gs:getCountryRequest>
<gs:name>Uruguay</gs:name>
</gs:getCountryRequest>
</soapenv:Body>
</soapenv:Envelope>
网络服务结果
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring xml:lang="en">The security token could not be authenticated or authorized; nested exception is org.apache.wss4j.common.ext.WSSecurityException: The security token could not be authenticated or authorized</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
您可以配置密码编码器bean:
@Configuration
public class PasswordEncoderConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return rawPassword.toString().equals(encodedPassword);
}
};
}
}
这是不可能的,qazxsw poi不支持密码编码。 qazxsw poi使用org.apache.wss4j.*
比较原始密码和候选密码。
BUUUUUUTTTT !!!!您可以实现另一个UsernameTokenValidator并将其设置为Wss4jSecurityInterceptor。
Wss4jSecurityInterceptor:
UsernameTokenValidator.java
Asevsdv
equal(...)
错误跟踪:
@Bean
public AbstractWsSecurityInterceptor securityInterceptor(){
Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();
securityInterceptor.setValidationActions("UsernameToken");
securityInterceptor.setValidationCallbackHandler(securitySpringBootCallbackHandler());
WSSConfig wssConfig = WSSConfig.getNewInstance();
wssConfig.setValidator(WSConstants.USERNAME_TOKEN, AppUsernameTokenValidator.class);
securityInterceptor.setWssConfig(wssConfig);
return securityInterceptor;
}