UsernameToken与CXF SOAP Web Service的正确WS-Policy配置求助
排查CXF UsernameToken策略拒绝问题
遇到CXF服务器拒绝UsernameToken策略的情况,大概率是策略配置、客户端请求格式或者CXF安全模块配置有不匹配的地方,我给你梳理几个核心排查方向:
1. 核对策略文件的命名空间与语法正确性
很多时候问题出在策略文件的命名空间遗漏或错误上,先确认你的UsernameTokenPolicy.xml开头是否包含了正确的命名空间声明:
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <!-- 你的策略内容 --> </wsp:Policy>
另外要检查sp:UsernameToken的约束是否和客户端发送的内容匹配:
- 如果策略里指定了
<sp:PasswordDigest/>,客户端必须发送哈希后的密码,而不是明文;反之如果是<sp:PasswordText/>,客户端要传明文。 - 如果策略包含
<sp:Nonce/>和<sp:Created/>,客户端的安全头里必须带上这两个元素,缺一不可。
2. 验证客户端安全头的格式是否符合策略要求
抓包或者用SOAPUI查看客户端发送的安全头,确认以下几点:
- UsernameToken必须嵌套在
wsse:Security节点下,且wsse的命名空间必须是http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd - 元素顺序是否符合WS-Security规范(比如Nonce、Created要在Password之前)
- 所有属性(比如
wsse:Type)是否正确设置
举个符合规范的安全头示例:
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:UsernameToken> <wsse:Username>testuser</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">...</wsse:Password> <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">...</wsse:Nonce> <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2024-05-20T12:00:00Z</wsu:Created> </wsse:UsernameToken> </wsse:Security>
3. 确认CXF的安全依赖与配置完整性
- 检查项目依赖是否包含
cxf-rt-ws-security,并且版本和CXF核心版本完全一致(版本冲突是常见坑) - 如果用Spring配置端点,确保CXF Bus已经启用了WS-Security特性:
<cxf:bus> <cxf:features> <cxf:ws-security/> <!-- 可选:开启日志方便排查 --> <cxf:logging/> </cxf:features> </cxf:bus>
- 确认
@Policy注解的路径是否正确,比如classpath:/ws/soap/UsernameTokenPolicy.xml是否对应项目resources下的实际文件位置。
4. 检查sp:IncludeToken的配置位置
sp:IncludeToken的生效需要放在正确的层级下,比如要包裹在sp:SupportingTokens或sp:RequiredTokens的Policy节点内,示例如下:
<sp:SupportingTokens> <wsp:Policy> <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:PasswordText/> </wsp:Policy> </sp:UsernameToken> </wsp:Policy> </sp:SupportingTokens>
如果sp:IncludeToken的属性值不对(比如用了Never或者不符合场景的值),也会导致策略验证失败。
5. 开启详细日志定位具体错误
这是最有效的排查手段,在日志配置(比如logback.xml)里添加WS-Security相关的DEBUG日志:
<logger name="org.apache.cxf.ws.security" level="DEBUG"/> <logger name="org.apache.wss4j" level="DEBUG"/>
日志里会明确告诉你拒绝的原因:是密码不匹配、缺少某个元素、命名空间错误,还是策略本身的语法问题。
如果能提供你的UsernameTokenPolicy.xml完整内容和客户端发送的安全头示例,我可以帮你更精准地定位问题。
内容的提问来源于stack exchange,提问作者Maciej Miklas
相关产品推荐
相关产品推荐

