JAX-WS,身份验证和授权 - 如何?
在 Web 服务中进行身份验证和授权的最佳方法是什么?
我正在开发一组 Web 服务,需要基于角色的访问控制。 使用 Metro - SOAP,没有 EJB 的简单 java。
- 我只想使用用户名和用户名对用户进行一次身份验证 密码,与数据库进行匹配。在随后的通话中。
- 我想使用某种会话管理。可能是一些 会话 ID,在登录时检索到客户端,并显示在所有会话中 来电。
到目前为止:
- 阅读 使用数据库进行身份验证 - 但我想要应用程序级验证;
阅读使用 jax 进行应用程序身份验证-ws - 但我不想每次都进行身份验证机制;
我想我可以使用 SOAP 处理程序来拦截所有消息,并使用消息附带的一些会话标识符令牌在处理程序中进行授权控制,该令牌可以与数据中保存的标识符进行匹配 我想我可以使用 SOAP 处理程序
编辑:
我还有一些问题:
- 如何知道被调用的网络方法的名称?
- 我应该使用什么样的令牌?
- 如何在调用之间传递此令牌?
编辑2
因为@ag112的回答:
我正在使用Glassfish。
我使用 WS-Policy 和 WS-Security 对消息进行加密和签名。使用相互证书身份验证。我想补充应用程序之间的消息级安全性,同时在消息级对用户进行身份验证和授权。
我只是在开发服务,我对客户几乎一无所知,只是知道它们可以用不同的语言创建。
在这一点上,我认为最重要的是做我需要做的事情来验证和验证用户,这是为客户端应用程序实现的最简单的方法。
What is the best way to do authentication and authorization in web services?
I am developing a set of web services, requiring role based access control.
Using metro - SOAP, simple java without EJBs.
- I want to Authenticate the user just one time, using username and
password, to be matched against a data base. In the subsequent calls. - I would like to use some kind of session management. Could be some
session id, retrieved to the client at login, to be presented in all
calls.
So Far:
- Read authentication using a database - but I want application level validation;
Read application authentication with jax-ws - but i don't want to do the authentication mechanism every time;
I think I can use a SOAP Handler, to intercept all the messages, and do the authorization control in the hander, using some session identifier token, that comes with the message, that can be matched against an identifier saved in the data base, in the login web method.
EDIT:
I still have some questions:
- How to know the name of the web method being called?
- What kind of token should I use?
- How to pass this token between calls?
EDIT 2
Because of @ag112 answer:
I'm using Glassfish.
I use WS-Policy and WS-Security to encrypt and sign the messages. Using Mutual Certificate Authentication. I would like to complement this message level security between applications, with the authentication and authorization for the users also in message level.
I am just developing the services, and I don't know almost nothing the clients, just that they could be created in different languages.
At this point I think the most important thing is to do what ever I need to do to authenticate and authentication the users, I the most easy way to be implemented for the client applications.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
@Luis:这是我的意见。
您的问题的确切解决方案取决于您期望的 Web 服务客户端类型,您是否可以控制 Web 服务客户端系统、您的应用程序服务器等......但假设您对 Web 服务客户端没有任何控制权,对于你这只是一个通过 HTTP 传输的 SOAP 消息,这里是可能的解决方案。
您当然可以执行会话管理和会话管理。消息级别或传输级别的身份验证。这意味着您可以在 SOAP 消息中包含会话令牌和身份验证令牌信息,也可以使用标准 HTTP 会话和 HTTP 身份验证机制。
当然,如果传输层是 HTTP,那么传输层解决方案要简单得多,并且是行业范围的标准。对于消息级别,可以使用 ws-security 等 ws 规范。
您的每个 Web 服务请求都是由唯一的 HTTP URI 标识的简单 HTTP GET/POST。
通常在 jax-ws Metro 环境中,WSServlet 是任何 Web 服务调用的入口 servlet,并最终将调用委托给正确的服务提供者实现类。由于您的应用程序将部署在 Web 服务器中,因此您可以利用 J2ee Web 容器提供的所有会话和身份验证设施。
由于您正在寻找基于角色的访问控制,因此我将在 web.xml 中使用标准
来指定在特定 HTTP URI 的情况下您希望拥有哪个角色。您可以使用标准 JAAS 登录模块,该模块可以进行身份验证并使用角色填充 JAAS 主题。如果 SOAP XML 中提供了用户名/密码,JAAS 登录模块还可以搜索/解析 SOAP XML 以检索这些信息。 JAAS/app 服务器会自动创建 auth token 并将其存储为 cookie,以便后续的每个请求都不需要再次经过身份验证过程。这都是 J2ee 标准。您可以在互联网上找到很多这方面的帮助。请让我知道您的应用程序服务器,以便我可以为您提供更多详细信息。如果您仍然想使用 SOAP 消息级会话管理、身份验证和授权流程,然后向您提供更多详细信息,我可以了解有关您的客户端的更多详细信息吗?
编辑1:
根据您的进一步输入,这是我的更多想法:
消息安全,即在服务器和客户端之间传输的每条消息都需要进行加密和签名。作为消息身份验证 - 您打算执行一次并向客户端提供会话令牌/身份验证令牌以供后续调用。
问题仍然存在:如果您在第一次身份验证的 SOAP 响应中放置唯一的会话标识符,您是否期望客户端解析 SOAP 响应 XML 并确保客户端在后续 SOAP 请求中每次都应向您发送会话标识符。
或
您希望保持会话管理对客户端透明,对于客户端来说,它需要第一次发送用户名/密码令牌,后续调用不需要任何用户名/密码令牌。在这种情况下,您需要依赖基于传输的会话管理(例如 HTTP cookie)。
现在什么最适合您取决于您的用例。您能告诉我预期的用例流程是什么吗?另一个系统(Web 服务客户端)如何对您的系统进行多个服务调用?是另一个系统用户驱动/某些后台进程吗?您希望仅第一个服务调用通过身份验证过程而不是后续调用的确切需求是什么?
PS:Glassfish 服务器提供了一种配置消息身份验证提供程序的方法,可自动启用/禁用消息级别身份验证。
编辑2:
我了解您不想在客户端应用程序中存储用户凭据,而 Web 服务服务器需要这些用户凭据。
OAuth 是开放标准协议,允许站点 A 访问站点 B 上的用户私有数据。最终的想法是站点 A 获取具有特定到期时间的身份验证令牌。因此,包含加密的用户凭据或 jsession id 的令牌可帮助您避免重新身份验证的需要。 您只需决定在客户端应用程序端将令牌保存在何处
如果传输是 HTTP 协议,则可以将令牌保留为 cookie。
话虽如此,当然每次传递用户凭据似乎都更容易和直接。
@Luis: Here are my inputs.
Well exact solution for your problem depends upon kind of web service clients you expect, do you have control over web service client system, your app server etc.....but assuming you don't have any control over web service client, for you it is just a SOAP message over HTTP transport, here is probable solution.
You can of course performs session management & authentication at message level or transport level. It means either you can have session token and auth token information in SOAP message or you can use standard HTTP Session and HTTP authentication mechanism.
Of course transport level solution is much simpler and industry wide standard in case if transport layer is HTTP. For message level, ws specifications like ws-security can be used.
Your each web service request is simple HTTP GET/POST identified by a unique HTTP URI.
Typically in jax-ws metro environment, WSServlet is one which entry servlet for any web service call and which eventually delegates the call to right service provider implementation class. Since you application is going to be deployed in web server, you can exploit all session and authentication facilities provided by J2ee web container.
Since you are looking for role-based access control, I would use standard
<web-resource-collection>
in web.xml to specify which role you would like to have in case of particular HTTP URI. You can use standard JAAS login module which can do authentication and populates the JAAS subject with role. If user name/password are provided in SOAP XML, JAAS login module can also search/parse SOAP XML to retrieve those information. JAAS/app server will automatically create auth token and store it as cookie so that each subsequent request need not to go through authentication process again. This is all J2ee standard. You can find plenty of help on internet on this. Please let me know your app server so that I can provide you additional details.If you still want to use SOAP message level session management, authentication & authorization process, then to provide you more details, may I know more details about your client side.
EDIT1:
Well based on your further inputs, here is my more thoughts:
Message security namely encryption and signature needs to happen each message travels between server and client. where as message authentication- you intend to do once and give a session token/auth token to client for subsequent calls.
Question still remains: if you put a unique session Identifier in SOAP response of first time authentication, do you expect client to parse SOAP response XML and ensure that client should send you session identifier each time in subsequent SOAP requests.
OR
You want to keep session management transparent to client and for client it needs to send username/password token first time and subsequent calls need not require any username/password token. In this case you would need to rely on transport based session management for e.g. HTTP cookies
Now what is the best for you depends upon your use case. Can you tell me what is expected use case flow? how another system (web service client) makes more than one service call to your system? Is another system user driven/some background process? What is exact need that you want only first service call to go through authentication process not subsequent calls?
PS: Glassfish server provides a way of configuring message authentication provider which automatically enables/disables message level authentication.
EDIT2:
I understand you do not want to store user credentials in client app and web service server need those user credentials.
OAuth is open standard protocol which allows site A to access user's private data on site B. Ultimate idea is site A gets auth token which has specific expiry time. So Token containing encrypted from of user credentials or jsession id help you avoid need of re-authentication. You only need to decide where you want to keep token at client app side
You can keep token as cookie if transport is HTTP protocol.
Having said that ofcourse passing user credentials each time seems bit easier and straight forward.
您还可以使用 OpenEJB。
它使用 JAAS 和 WS-Security。
我希望该链接有用。
You can also go for OpenEJB.
It used JAAS with WS-Security.
I hope the link is useful.
在获得所有帮助后,我创建了这个答案来简化并总结了讨论的所有想法。
这些问题有 2 个必要条件:
在ag112的帮助下,这很难做到,或者以任何方式都很难做到。所以这里是结论:
每次都提供凭据(将其放在 SOAP 标头中);
会话管理。
我更喜欢第一个,因为消息级别是最大的要求。
After all the help, I create this answer to simplify, and summarize all the ideas that was discussed.
The questions has 2 requisites:
With ag112 help, this is hard to do, or to elegant in any way. So here are to conclusions:
credentials every time (place it in SOAP header);
session management.
I prefer the first one, because the message level was the biggest requisite.
由于没有答案,根据@unhillbilly的建议,我回答了我自己的问题,以及迄今为止的进展:
使用 SOAP 处理程序查找正文中第一个元素的名称。
我决定使用 128 位令牌来代表每个会话。 Web 服务仍然是无会话的,关键仅用于授权目的。
对于登录 Web 方法,结果具有令牌,在后续的每次调用中,令牌是一个参数。
有更好的答案吗?
As had no answers, following @unhillbilly advise, I answer my own question, with the progress so far:
Using a SOAP handler, finding the name of the first element in the body.
I decide to use a 128 bits token, representing each session. The Webservices, continue to be session-less, the key is just for authorizations purposes.
For the login web method the result has the token, in each subsequent calls, the token is a parameter.
is there a better answer?