配置两个cxf jaxrs客户端以使用相同的会话(cookie)

问题描述 投票:8回答:2

我想使用apache cxf用jaxrs客户端连接到REST服务器。服务器具有一个要进行身份验证的URL,以及一些用于进行实际工作的URL。登录后,服务器创建一个会话并保持连接打开30分钟。我的问题是客户端不存储cookie,并且我总是在服务器上获得一个新的(未经身份验证的)会话。

我在spring应用程序上下文中配置了客户端。

<jaxrs:client id="loginResource" 
    serviceClass="com.mycompany.rest.resources.LoginResource" 
    address="${fsi.application.url}">
</jaxrs:client>
<jaxrs:client id="actionResource" 
    serviceClass="com.mycompany.rest.resources.ActionResource" 
    address="${fsi.application.url}">
</jaxrs:client>

如何配置两个客户端以使用相同的会话或在客户端之间共享会话cookie?

session rest cookies cxf jax-rs
2个回答
2
投票

我一直在同一个问题上挣扎,我终于找到了解决方案。

1)让客户端保留cookie。

WebClient.getConfig(proxy).getRequestContext().put(
        org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE);

也许有一种方法可以通过配置还是以编程方式完成上述任务。

2)将cookie从一个客户端复制到另一个客户端。

public static void copyCookies(Object sourceProxy, Object targetProxy) {
    HTTPConduit sourceConduit = WebClient.getConfig(sourceProxy).getHttpConduit();
    HTTPConduit targetConduit = WebClient.getConfig(targetProxy).getHttpConduit();
    targetConduit.getCookies().putAll(sourceConduit.getCookies());
}

使用代理A进行身份验证之后,我调用上述方法与代理B共享其cookie,这将完成实际工作。


0
投票

我使用以下请求/响应过滤器在每个请求中传递会话ID:

ClientResponseFilter >>用于从会话cookie中提取会话IDClientRequestFilter >>在每个请求中将会话ID作为cookie头传递

private class SessionIdRequestFilter implements ClientRequestFilter, ClientResponseFilter {
    /** cookie header key */
    private static final String COOKIE_KEY = "Cookie"; //$NON-NLS-1$

    /** name of the session cookie */
    private String cookieName = "JSESSIONID";

    /** holds the session id from the cookie */
    private String sessionId;

    @Override
    public void filter(ClientRequestContext request) throws IOException {
        // append session cookie to request header
        if (!request.getHeaders().containsKey(COOKIE_KEY) && sessionId != null) {
            request.getHeaders().add(COOKIE_KEY, getCookieName() + "=" + sessionId); //$NON-NLS-1$
        }
    }

    @Override
    public void filter(ClientRequestContext request, ClientResponseContext response) throws IOException {
        // find sessionId only if not already set
        if (sessionId == null) {
            Map<String, NewCookie> cookies = response.getCookies();
            if (cookies != null && !cookies.isEmpty()) {
                NewCookie cookie = cookies.get(getCookieName());
                if (cookie != null) {
                    sessionId = cookie.getValue();
                }
            }
        }
    }

    private String getCookieName() {
        return cookieName;
    }
}

注册过滤器使用:

RestClientBuilder.newBuilder().baseUri(apiUri).register(new SessionIdRequestFilter());
© www.soinside.com 2019 - 2024. All rights reserved.