jwt - 即使 onBehalfOf 中有 SAML 令牌,CXF STSClient 也会要求提供用户+密码
问题描述
我正在使用 CXFSTSClient
代表用户请求 JWT 令牌,以便我可以调用 REST 服务。
我有一个有效的 SAML 令牌并尝试STSClient
像这样配置:
stsClient.setTokenType("urn:ietf:params:oauth:token-type:jwt");
stsClient.setKeyType("http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer");
stsClient.setOnBehalfOf(samlToken.getToken());
stsClient.setEnableAppliesTo(true);
// Not sure about these.
stsClient.setSendRenewing(false);
stsClient.setKeySize(0);
stsClient.setRequiresEntropy(false);
final Map<String, Object> requestContext = Preconditions.checkNotNull(stsClient.getRequestContext());
requestContext.put(SecurityConstants.USERNAME, name); // Without this, I get "No username available"
SecurityToken result = stsClient.requestSecurityToken(appliesTo);
但是当方法失败时:
Caused by: org.apache.cxf.interceptor.Fault: No callback handler and no password available
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleBinding(TransportBindingHandler.java:182)
at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessageInternal(PolicyBasedWSS4JOutInterceptor.java:180)
at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:110)
at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:97)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:441)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:356)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314)
at org.apache.cxf.ws.security.trust.AbstractSTSClient.issue(AbstractSTSClient.java:874)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:71)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:65)
at org.apache.cxf.ws.security.trust.STSClient.requestSecurityToken(STSClient.java:61)
Caused by: org.apache.cxf.ws.policy.PolicyException: No callback handler and no password available
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractCommonBindingHandler.unassertPolicy(AbstractCommonBindingHandler.java:93)
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getPassword(AbstractBindingBuilder.java:1042)
at org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.addUsernameToken(AbstractBindingBuilder.java:839)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.addSignedSupportingTokens(TransportBindingHandler.java:115)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleNonEndorsingSupportingTokens(TransportBindingHandler.java:208)
at org.apache.cxf.ws.security.wss4j.policyhandlers.TransportBindingHandler.handleBinding(TransportBindingHandler.java:167)
... 16 common frames omitted
由于我有一个 SAML 令牌,我希望 STSClient 不再需要用户名或密码。
如何告诉 CXF /STSClient
跳过addUsernameToken()
方法调用?
解决方案
问题出在服务的 WSDL 定义中。
WSDL 中的每个端口都附加到一个 URL 和一个绑定。绑定有一个策略。这种情况下的策略请求用户名和密码。UsernameToken
在 WSDL 中查找。
你需要的是一个不需要这个的端口。我不是这方面的专家,但从我看到的例子来看,政策中不能有SignedSupportingTokens
元素,只有Wss11
和Trust13
元素。
如果没有这个元素,CXF 将在代码中采用不同的路径,错误就会消失。
推荐阅读
- python - 在 Python 中查找下一个素数
- vue.js - Safari iframe 的 service worker 无限循环,iframe 是白屏(其他浏览器不行,新标签页不行)
- amazon-web-services - CodeBuild 定制
- graphql - 如何从 GraphQL 模式生成 Kotlin 和/或 Java 数据模型
- c# - 从 JsonConverter.ReadJson 访问已经反序列化的属性
- android - 如何在 android 对话框片段中使特定的文本参数加粗
- ios - Swift-将数组分配给collectionviewcell中的tableview
- linux - cron 应该能够发送带有 Unicode 字符的电子邮件吗?
- laravel - Laravel 我需要两个控制器来处理两个商店功能吗?
- javascript - 有条件地加入 JavaScript 中的一些数组项