使用 Spring Security 在 Web 应用程序和 RESTful 服务之间共享安全上下文
Posted
技术标签:
【中文标题】使用 Spring Security 在 Web 应用程序和 RESTful 服务之间共享安全上下文【英文标题】:Sharing Security Context between web app and RESTful service using Spring Security 【发布时间】:2013-04-16 02:22:09 【问题描述】:我们正在为一个带有 UI Web 模块 (Spring MVC) - 客户端和 RESTful 服务 Web 模块 (CXF) - 服务器的绿地项目设计安全性,将作为单独的 war 文件部署在同一个 Websphere 应用程序中服务器。系统应该使用 Spring Security 保护,针对 LDAP 进行身份验证并针对数据库进行授权。我们一直在寻找在 2 个应用程序之间共享安全上下文的最佳解决方案,以便用户可以在 Web UI 中进行身份验证并调用其对安全 RESTful 服务的 AJAX 调用。找到的选项:
OAuth:对我们的要求来说似乎有点过头了,引入了相当复杂的身份验证过程,据报道还存在一些企业集成问题
CAS:相当于设置企业 SSO 解决方案,超出了我们的参与范围
基于容器 (Websphere) 的安全性,虽然 Spring Security 不推荐,但我们不清楚这是否可以为我们的特定需求提供解决方案我们正在寻找更简单的解决方案。我们如何在 2 个应用程序之间传播安全上下文?我们是否应该在 UI Web 应用程序中实现身份验证,然后在数据库中持久化会话,以便 RESTful 服务查找? CXF可以提供解决方案吗?我们阅读了许多关于生成可以传递的“安全令牌”的线程,但是如何使用 Spring Security 完全做到这一点,它是否足够安全?
期待任何想法或建议。
【问题讨论】:
一个简单的解决方案(虽然不是一个好的解决方案)是您可以从一个 web 应用程序到另一个 web 应用程序进行跨上下文调用,以检查用户是否已登录。见docs.oracle.com/javaee/6/api/javax/servlet/… 如果我的回答对您有帮助,您可以接受并推广。 【参考方案1】:您希望能够代表在 UI Web 模块中认证的用户在服务器上执行 REST Web 服务。 您描述的要求称为 SingleSignOn。 最简单的方法是在 REST WS 调用期间传递带有用户名的 HTTP 标头。 (我希望您的 REST 客户端允许这样做)。 要以安全的方式执行此操作,请使用以下方法之一:
-
在REST客户端加密用户名,在REST服务器解密
确保标头是从本地主机发送的(因为您的应用程序部署在同一个容器上)
因此,使用 SpringSecurity 保护两个应用程序对 LDAP 进行身份验证。
在第一个应用程序(Rest Client)中使用常规表单身份验证
在第二个应用程序(Rest Server)中添加您自己的PreAuthenticatedProcessingFilter
:
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#d0e6167
已编辑
“身份验证”是验证主体身份的过程。 在我们的例子中,REST 客户端(Spring MVC 应用程序)和 REST 服务器(CXF 应用程序)都根据 LDAP 验证身份。 LDAP “说”OK 或 Not。 LDAP 是一个用户存储库。它是无状态的,不记得以前的状态。它应该保存在应用程序中。
据我了解,用户不会直接访问 REST 服务器——用户总是访问 REST 客户端。因此,当用户访问 REST 客户端时,他/她提供用户名和密码,REST 客户端针对 LDAP 进行身份验证。因此,如果 REST 客户端访问 REST 服务器,则用户已通过身份验证,并且 REST 客户端知道他的姓名。
因此,如果请求带有用户标头名称的 REST 服务器 - REST 服务器肯定知道用户已通过身份验证,并且不应再次针对 LDAP 对其进行身份验证。 (标题应以上述安全方式传递)。 Rest Server 应该使用用户名来访问 LDAP 并在不提供用户密码的情况下收集相关的用户信息(因为用户已经通过身份验证)。
【讨论】:
感谢您的回答迈克尔。在 REST 客户端认证成功后,如果我们只是将 REST 客户端的用户名传递给 REST 服务器,那么 REST 服务器如何知道用户通过了认证呢? LDAP 服务器会为这个用户维护一个会话吗?那么 REST 服务只需要轮询 LDAP 服务器来验证身份验证状态吗?抱歉,我没有使用 LDAP 的经验。另外,后续请求会发生什么?我们会在每个请求中继续传递用户名吗?还是 PreAuthenticatedProcessingFilter 会创建一个令牌? 我编辑了答案。我将无法教你如何在 SpringSecurity 中做到这一点——它有很好的文档并且有 LDAP 示例。我想帮助解决您的设计问题。以上是关于使用 Spring Security 在 Web 应用程序和 RESTful 服务之间共享安全上下文的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Security 保护 Web 应用程序免受 CSRF 攻击
Spring web security:@EnableWebSecurity 过时了吗?
如何使用 Spring Security 保护 REST Web 服务
如何在我的 Spring 4.0 RestFul Web 服务上实现 Spring Security?