【问题标题】:How to dynamically add HTTP headers in CXF client?如何在 CXF 客户端中动态添加 HTTP 标头?
【发布时间】:2014-12-02 14:47:43
【问题描述】:

我正在使用Spring 和CXF 创建一个soap webservice 客户端。

Web 服务需要 HTTP 标头 Authorization=[pass] 进行身份验证。到目前为止,我实现如下:

Map<String, Object> context = ((BindingProvider) port).getRequestContext();
Map<String, List<String>> headers = new HashMap<>();
headers.put("Authorization", Arrays.asList("Basic pass")); //fixed value so far
context.put(MessageContext.HTTP_REQUEST_HEADERS, headers);

但现在我必须根据实际执行客户端的用户动态更改基本通行证。

问题:当我将 CXF 与 Spring 一起使用时,我的 CXF 客户端由 Spring 管理和共享代理。 因此,每当我更改port 中的 HTTP 标头时,它都会影响所有实例!

如何在发送 Web 服务请求期间动态添加 HTTP 身份验证标头?

我必须准确地创建一个 http 标头,例如:Authorization=[pass]

【问题讨论】:

    标签: java spring web-services soap cxf


    【解决方案1】:

    我假设您真正想做的是 HTTP BASIC 身份验证。 CXF 中有定义的 API 来设置用户名/密码以进行 BASIC 身份验证。这会做你想做的事:

    HTTPConduit httpConduit = (HTTPConduit) ClientProxy.getClient(stub).getConduit();
    httpConduit.getAuthorization().setUserName("username");
    httpConduit.getAuthorization().setPassword("password");
    

    还有其他选择,例如将用户名/密码直接放入请求上下文中:

    AuthorizationPolicy authzPolicy = new AuthorizationPolicy();
    authzPolicy.setUserName("username");
    authzPolicy.setPassword("password");
    ((BindingProvider) stub).getRequestContext().put(AuthorizationPolicy.class.getName(), authzPolicy); 
    

    【讨论】:

    • 这将在代理请求上下文中静态更改 HTTP 标头。这适用于单个用户,但不是动态线程安全的。如果您有线程安全的解决方案,例如动态添加到 xml 请求的 http 标头,请告诉我。
    • 无论如何,您使用AuthorizationPolicy 的解决方案可能应该是实现基本授权的首选方式,而不是手动构建http 标头。谢谢你。
    • @membersound 我试图以线程安全的方式获得相同的行为。现在我在客户端对象上使用拦截器,这不是线程安全的,会导致问题。因此,我每次都需要创建一个端口。如果您有任何与此相关的有用信息,请分享。
    • @Sachin 差不多 3 年前,所以我记不清了。但我不认为这是可能的。我创建了一个带有分配凭据的惰性“端口缓存”。因此,您必须为要使用的每个不同的凭据对创建一个新端口,但仅在首次访问时实例化并缓存它。
    • 好的。谢谢你的建议:)
    【解决方案2】:

    也许您应该将 Spring 配置为在自己的会话中与每个用户一起工作,这样每个用户的客户端实例都会不同。对于客户端实例,您可以执行类似的操作:

    Client proxy = ClientProxy.getClient(stub);
    
    // Creating HTTP headers
    Map<String, List<String>> headers = new HashMap<String, List<String>>();
    headers.put("Authorization", Arrays.asList("Basic pass"));
    
    // Add HTTP headers to the web service request
    proxy.getRequestContext().put(Message.PROTOCOL_HEADERS, headers);
    

    【讨论】:

    • 但这会添加一个soap:header 元素,对吧?我需要的是一个完全命名为“授权”的 HTTP 标头元素,以便创建 Authorization=[Basic pass] http 标头。而根据肥皂服务的设计,“基本通行证”必须是base64(username:password) 编码字符串。我认为使用 httpconduit 是不可能的,不是吗?
    • 新版本怎么样? =)
    • 这将在代理请求上下文中静态更改 HTTP 标头。这适用于单个用户,但不是动态线程安全的。
    猜你喜欢
    • 2013-09-24
    • 1970-01-01
    • 2015-09-15
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多