【问题标题】:JAXWS and sessionsJAXWS 和会话
【发布时间】:2010-05-01 23:41:54
【问题描述】:

我对编写 Web 服务还很陌生。我正在使用 JAXWS 开发 SOAP 服务。我希望能够让用户登录并在我的服务中知道哪个用户正在发出命令。换句话说,有一些会话处理。

我见过的一种方法是使用 cookie 并从我的 Web 服务访问 HTTP 层。然而,这依赖于使用 HTTP 作为传输层(我知道 HTTP 几乎总是传输层,但我是一个纯粹主义者)。

有没有更好的方法让服务层不知道传输层?有什么方法可以用 servlet 过滤器完成这个吗?我希望答案尽可能与框架无关。

【问题讨论】:

    标签: java web-services soap session jax-ws


    【解决方案1】:

    我正在使用 JAXWS 开发 SOAP 服务。我希望能够让用户登录并在我的服务中知道哪个用户正在发出命令。换句话说,有一些会话处理。

    传统的 Web 服务本质上是无状态的,Web 服务中没有会话处理(据说与识别调用者无关)。

    如果您想要求您的用户通过身份验证才能调用服务,传统的方法是:

    1. 公开返回身份验证令牌的“身份验证”Web 服务(传递用户凭据)。
    2. 让用户先调用此身份验证。
    3. 让用户在后续调用“业务”Web 服务时在自定义标头中传递令牌。

    在服务器端:

    1. 拒绝任何不包含有效令牌的调用。
    2. 在一段时间不活动后使令牌失效

    您可以为此方法实施自定义解决方案(这是一种高度互操作的解决方案)。或者你可以使用WS-Security/UsernameTokens,它提供了类似的开箱即用的东西。 WS-Security 是一个标准(Metro 实现了它),它不是特定于“框架”的。

    【讨论】:

    • 出色的答案。非常感谢。
    【解决方案2】:

    正如您所提到的,servlet 过滤器可以提供解决方案的基础。使用过滤器将当前会话详细信息(例如会话上下文映射)存储在 threadLocal 存储中。这是作为您的应用程序类实现的,因此与传输无关。您的服务只是使用静态方法来获取当前上下文,不知道它来自哪里。

    例如

    class ServiceSessionContext
    {
        static ThreadLocal<Map> local = new ThreadLocal<Map>();
    
        // context set by the transport layer, e.g. servlet filter
        static public void setContext(Map map)
        {
            local.put(map);
        }
    
        // called when request is complete
        static public void clearContext()
        {
            local.put(null);
        }
    
        // context fetched by the service
        static public Map getContext()
        {
            return local.get();
        }
    }    
    

    【讨论】:

    • 谢谢,我想我可以使用这种模式将上面提到的令牌传递到我的服务层。
    猜你喜欢
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 2018-04-06
    • 1970-01-01
    • 2010-10-20
    • 2015-10-10
    相关资源
    最近更新 更多