编程使用Spring Security

我在Wicket Auth Project中使用Wicket作为我的表示层,因此我将它与Spring Security集成在一起。 这是Wicket为我所authentication的方法:

@Override public boolean authenticate(String username, String password) { try { Authentication request = new UsernamePasswordAuthenticationToken( username, password); Authentication result = authenticationManager.authenticate(request); SecurityContextHolder.getContext().setAuthentication(result); } catch (AuthenticationException e) { return false; } return true; } 

我的Spring Security XMLconfiguration的内容是:

 <http path-type="regex"> <form-login login-page="/signin"/> <logout logout-url="/logout" /> </http> <global-method-security secured-annotations="enabled" /> <authentication-manager alias="authenticationManager"/> <authentication-provider user-service-ref="userService"> <password-encoder ref="bcryptpasswordencoder" /> </authentication-provider> 

2.3.6节 会话固定攻击保护参考文档说:

会话修复攻击是一个潜在的风险,因为恶意攻击者可能通过访问一个站点来创build一个会话,然后劝说另一个用户使用同一个会话login(通过发送一个包含会话标识符作为参数的链接)例)。 Spring Security通过在用户login时创build一个新会话来自动防止这种情况发生。如果您不需要此保护,或者与其他需求冲突,则可以使用session-fixation-protection属性来控制行为,其中有三个选项:

  • migrateSession – 创build一个新的会话并将现有的会话属性复制到新的会话中。 这是默认的。
  • 没有 – 不要做任何事情。 原来的会议将被保留。
  • newSession – 创build一个新的“干净的”会话,而不复制现有的会话数据。

身份validation的作品,但我作为我相当新的春季安全我有一些问题,我也需要答案:

  • 通常为了login,我会将身份validation信息发送到j_spring_security_check并让Spring Security执行实际的身份validation代码。 我想要防范会话修复攻击,当我像我一样执行程序化login时,我会得到它吗? 如果不是,我需要做些什么才能得到它?
  • 我如何执行程序化注销?
  • 正如我将使用程序化login和注销,我如何禁用Spring拦截这些URL?

更新:对于会话修复攻击保护,似乎需要使用签名startNewSessionIfRequired(HttpServletRequest request, boolean migrateAttributes, SessionRegistry sessionRegistry)来调用SessionUtils类中的方法。

如何获得我需要传入的SessionRegistry实例? 我找不到任何方法来为它创build一个别名ID,或者如何获得它的ID或名称。

也许这不是你的问题的完整答案,但也许它可以帮助你。

在不使用程序化login的情况下调用代码,但可以在这里find标准代码:

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

我想你在你的代码中受到了这个启发。 它看起来很相似。

同样,在标准方法中访问/j_spring_security_logout时执行的代码也可以在这里find:

org.springframework.security.ui.logout.LogoutFilter

LogoutFilter调用多个处理程序。 我们使用的处理程序叫做: org.springframework.security.ui.logout.SecurityContextLogoutHandler ,所以你可以在你的方法中调用相同的代码。

你确实会受到会话固定攻击。 为了弥补这一点,你可以再次被Spring代码“启发”。 要创build一个新的会话,你显然需要访问httpsession,所以你可能需要做一些重构。

如果你看到SessionUtils的方法。 startNewSessionIfRequired

这会将authentication迁移到新的会话。 你也许可以直接调用这个方法,或者稍微重构一下代码。

至于编程注销,只要在需要登出的时候调用session.invalidate()就不会错。 这将从一般的安全angular度做所有必要的事情,但请记住,虽然您可能需要清理会议上的一些事情。 如果您有一套非常复杂的filter等,并且您需要确保用户注销剩余的请求,那么您可以添加:

 SecurityContextHolder.getContext().setAuthentication(null); 

至于截取的url,你可以将它们设置为未使用的东西,忽略它! 我不确定是否可以closuresconfiguration中的拦截 – 如果你真的想删除它,那么看看AuthenticationProcessingFilter – 你可以自定义这个。 如果你这样做,那么你将不得不手动设置春季安全xml,而不是使用提供的名称空间。 这不是太难 – 看看一些较旧的文档,你会看到如何做到这一点。

希望这可以帮助!

1)编程注销

  1. 调用HttpServletRequest.getSession(false).invalidate
  2. 调用SecurityContextHolder.clearContext()

2)告诉Spring Security不要拦截某些URL,这一种取决于你的应用程序URL空间的设置。 如果你的所有页面(/ logIn和/ logout除外)都存在于context / myApp中,那么你可以这样做:

 <http ....> <intercept-url pattern="/myApp/**" ..> .... </http> 

我有一个编程login问题。 我调用了所有的authenticationManager.authenticate(...)SecurityContextHolder.getContext().setAuthentication(...)方法,但是Session有一些问题。 我不得不添加以下几行来正确pipe理会话:

 HttpSession session = request.getSession(); session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext()); 

从上面发布的示例代码中不清楚这一点。 有关更多信息,请参阅http://forum.springsource.org/showthread.php?t=69761

要进行编程注销,也可以抛出org.springframework.security.core.AuthenticationException 。 例如, SessionAuthenticationException 。 在这种情况下, ExceptionTranslationFilter启动注销。

你可以试试这个

  try { HttpSession session = request.getSession(false); if (session != null) { session.invalidate(); } SecurityContextHolder.clearContext(); } catch (Exception e) { logger.log(LogLevel.INFO, "Problem logging out."); }