JAX-WS,身份validation和授权 – 如何?

在Web服务中进行身份validation和授权的最佳方法是什么?

我正在开发一组Web服务,需要基于角色的访问控制。 使用metro – SOAP,没有EJB的简单java。

  • 我想使用用户名和密码对用户进行一次身份validation,以便与数据库进行匹配。 在随后的电话中。
  • 我想使用某种会话管理。 可以是在登录时检索到客户端的某个会话ID,以便在所有呼叫中显示。

至今:

  • 使用数据库读取身份validation – 但我想要应用程序级别validation;
  • 使用jax-ws读取应用程序身份validation – 但我不想每次都执行身份validation机制;

  • 我想我可以使用SOAP处理程序拦截所有消息,并使用消息附带的一些会话标识符令牌在hander中执行授权控制,该令牌可以与保存在数据库中的标识符匹配,登录Web方法。

编辑:

我还有一些问题:

  • 如何知道被调用的Web方法的名称?
  • 我应该使用什么样的令牌?
  • 如何在通话之间传递此令牌?

编辑2

因为@ ag112回答:

我正在使用Glassfish。

我使用WS-Policy和WS-Security来加密和签名消息。 使用相互证书身份validation。 我想在应用程序之间补充此消息级别的安全性,同时在消息级别对用户进行身份validation和授权。

我只是在开发服务,我几乎不知道客户,只是他们可以用不同的语言创建。

在这一点上,我认为最重要的是做我需要做的事情来validation和validation用户,我是客户端应用程序最简单的实现方式。

@Luis:这是我的输入。

您的问题的确切解决方案取决于您期望的Web服务客户端类型,您是否可以控制Web服务客户端系统,您的应用程序服务器等…..但假设您对Web服务客户端没有任何控制权,你只是一个通过HTTP传输的SOAP消息,这是可能的解决方案。

您当然可以在消息级别或传输级别执行会话管理和身份validation。 这意味着您可以在SOAP消息中拥有会话令牌和身份validation令牌信息,也可以使用标准HTTP会话和HTTP身份validation机制。

当然,如果传输层是HTTP,则传输级解决方案更简单且行业范围更广。 对于消息级别,可以使用ws-security之类的ws规范。 您的每个Web服务请求都是由唯一HTTP URI标识的简单HTTP GET / POST。 通常在jax-ws metro环境中,WSServlet是用于任何Web服务调用的入口servlet,并最终将调用委托给正确的服务提供者实现类。 由于您的应用程序将部署在Web服务器中,因此您可以利用J2ee Web容器提供的所有会话和身份validation工具。

由于您正在寻找基于角色的访问控制,因此我将在web.xml中使用标准的来指定在特定HTTP URI的情况下您希望拥有哪个角色。 您可以使用标准JAAS登录模块,该模块可以进行身份​​validation并使用角色填充JAAS主题。 如果在SOAP XML中提供用户名/密码,则JAAS登录模块还可以搜索/解析SOAP XML以检索这些信息。 JAAS / app服务器将自动创建身份validation令牌并将其存储为cookie,以便每个后续请求都不需要再次通过身份validation过程。 这是所有J2ee标准。 你可以在互联网上找到很多帮助。 请让我知道您的应用服务器,以便我可以为您提供更多详细信息。

如果您仍想使用SOAP消息级会话管理,身份validation和授权过程,那么为了向您提供更多详细信息,我是否可以了解有关您客户端的更多详细信息。

编辑1:基于您的进一步输入,这是我的更多想法:消息安全性即加密和签名需要在服务器和客户端之间传递每个消息。 作为消息身份validation的地方 – 您打算执行一次并为客户端提供会话令牌/身份validation令牌以进行后续调用。

问题仍然存在:如果在第一次身份validation的SOAP响应中放置一个唯一的会话标识符,您是否希望客户端解析SOAP响应XML并确保客户端每次在后续SOAP请求中都应向您发送会话标识符。 或者您希望会话管理对客户端保持透明,对于客户端,它需要首次发送用户名/密码令牌,后续调用不需要任何用户名/密码令牌。 在这种情况下,您需要依赖基于传输的会话管理,例如HTTP cookie

现在最适合你的是取决于你的用例。 你能告诉我预期的用例流程是什么吗? 另一个系统(Web服务客户端)如何对您的系统进行多个服务调用? 是另一个系统用户驱动/一些后台进程? 您只需要第一次服务呼叫才能通过身份validation过程而不是后续呼叫的确切需求是什么?

PS:Glassfish服务器提供了一种配置消息身份validation提供程序的方法,它自动启用/禁用消息级别身份validation。

EDIT2:我知道您不希望在客户端应用程序中存储用户凭据,并且Web服务服务器需要这些用户凭据。 OAuth是开放标准协议,允许站点A访问站点B上的用户私有数据。最终的想法是站点A获取具有特定到期时间的身份validation令牌。 因此,包含来自用户凭据或jsession id的加密的令牌可帮助您避免重新进行身份validation。 您只需要决定在客户端应用程序端保留令牌的位置如果传输是HTTP协议,则可以将令牌保留为cookie。

说过每次传递用户凭据的过程似乎更容易和直接。

在所有帮助之后,我创建了这个简化的答案,并总结了所讨论的所有想法。

这些问题有两个必要条件:

  • 消息级安全性;
  • 一次validation。

有了ag112的帮助,这很难做到,或者以任何方式优雅。 所以这是结论:

  • 对于消息级安全性,每次都发送用户凭证(将其放在SOAP头中);
  • 一次性身份validation使用传输级别安全性,并执行会话管理。

我更喜欢第一个,因为消息级别是最大的必要条件。

你也可以去OpenEJB 。

它使用JAAS和WS-Security。

我希望这个链接很有用。

由于没有答案,在@unhillbilly建议之后,我回答了我自己的问题,到目前为止取得了进展:

如何知道被调用的Web方法的名称;

使用SOAP处理程序,查找正文中第一个元素的名称。

我应该使用什么样的代币;

我决定使用128位令牌,代表每个会话。 Webservices继续是无会话的,关键仅在于授权目的。

如何在调用之间传递此令牌。

对于登录Web方法,结果具有令牌,在每个后续调用中,令牌是参数。

有更好的答案吗?