我正在开发一个使用 Spring MVC 和 Spring REST 的应用程序,它分为 2 个服务器,后端是 Spring REST 接口(interface),前端是普通的 SPRING MVC 应用程序。然而,我有一些安全要求,特别是对于 MVC 服务器前端,例如
- 每个用户只有一个 Activity session
- 指定时间后 session 超时
- 能够从应用程序上的表单创建新角色,并将这些角色应用于在运行时动态访问的 URL,而不是硬编码到配置中。
我的问题是
- 有没有办法实现自定义登录模块,该模块将对用户进行身份验证,但仍使用 Spring Security 来管理登录和注销后的访问控制。
- 我看到的所有示例都使用 Spring 配置文件中配置的预定义角色,但是我们的要求是我们不知道系统中的角色以及它们在部署时将被允许访问的 URL,所有这些都是由管理员通过 UI 配置的,所以问题是我可以使用任何示例来了解如何在 Spring Security 中处理此问题。
- 最后是上面提到的单次 session 要求。
任何指示将不胜感激。
最佳答案
1) 有没有办法实现自定义登录模块,该模块将对用户进行身份验证,但仍然使用 Spring Security 来管理登录和注销后的访问控制。
是的。您可以通过实现 org.springframework.security.authentication.AuthenticationProvider 并使其成为一个 bean(对其进行注释或在 XML 中)来提供自己的身份验证机制:
@Service("myAuthenticationProvider") public class TangoAuthenticationProvider implements AuthenticationProvider{
@Override public boolean supports(Class<?> authentication) { //your code } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { //your code }
然后,并指示 Spring security 使用它(在您的安全上下文中):
<authentication-manager>
<authentication-provider ref="tangoAuthenticationProvider" />
</authentication-manager>
参见this question ,当然还有spring security doc .
2)动态创建的角色:我无法回答这部分,没有这方面的经验。
3) 单次 session 要求
也许 Spring Security 中内置了这样的机制(您必须对此进行研究),但我认为您可以使用简单的 session 监听器和前面提到的自定义身份验证机制来实现它:
- 将 session ID 字段添加到您的用户实体(或其他位置,但以某种方式将您的用户 ID 与 session ID 相关联)
创建一个服务,允许存储与其 ID 关联的 session 的引用,并通过其 ID 提供对 session 的访问。您可以使用静态 HashMap ,或者单例,或者更好的是,具有大致以下接口(interface)的 Spring 服务 bean(我们将其称为 session 存储库):
public void putSession(String id, HttpSession session); public HttpSession getSessionById(String id);
在您的身份验证提供程序中,成功登录后,将用户的 session ID 字段设置为当前 session ID
- 在身份验证逻辑中,如果用户的 sessionId 字段不为空,则禁止身份验证(那么您不需要对 session 机制的引用),或者更可能是真正的要求,通过使用用户的 sessionId 字段的值从 session 存储库获取用户的其他正在进行的 session ,从而使该 session 无效
- 在 session 监听器中: 创建 session 时:将 session 存储在 session 存储库中 session 删除时:如果有登录用户,则清除其sessionId字段;清除对 session 的引用以避免内存泄漏。
这是与安全性(跨 session 内容)相关的敏感代码,因此应该非常仔细地编写和测试它!
希望对您有所帮助。
关于java - Spring 安全要求和问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17108159/