程序化使用Spring Security

37 java spring wicket spring-security

我正在将Wicket与Wicket Auth项目一起用于我的表示层,因此我将其与Spring Security集成在一起.这是Wicket为我进行身份验证调用的方法:

@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;
}
Run Code Online (Sandbox Code Playgroud)

我的Spring Security XML配置的内容(内部)是:

<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>
Run Code Online (Sandbox Code Playgroud)

2.3.6.会话修复攻击保护参考文档说:

会话固定攻击是潜在的风险,恶意攻击者可以通过访问站点创建会话,然后说服其他用户使用相同的会话登录(通过向他们发送包含会话标识符作为参数的链接,例).Spring Security通过在用户登录时创建新会话来自动防止这种情况.如果您不需要此保护,或者它与其他一些要求冲突,您可以使用session-fixation-protection属性控制行为,有三种选择:

  • migrateSession - 创建新会话并将现有会话属性复制到新会话.这是默认值.
  • none - 什么都不做.原始会话将保留.
  • newSession - 创建新的"干净"会话,而不复制现有的会话数据.

身份验证有效,但我是Spring Security的新手,我还有一些问题需要解答:

  • 通常,对于登录,我会将身份验证信息POST,j_spring_security_check并让Spring Security执行实际的身份验证代码.我希望能够防止会话固定攻击,当我执行程序化登录时,我会得到它吗?如果没有,我需要做些什么才能得到它?
  • 如何执行程序化注销?
  • 由于我将使用程序化登录和注销,如何禁止Spring拦截这些URL?

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

如何获取我需要传递的SessionRegistry实例?我找不到任何方法为它创建别名ID,或者如何获取它的ID或名称.

Grz*_*zki 23

也许这不是你问题的完整答案,但也许它可能对你有所帮助.

当您不使用程序化登录时调用代码,但在此处可以找到标准代码:

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

我猜你在代码中受到了这个启发.它看起来非常相似.

类似地,您/j_spring_security_logout在标准方法中访问时执行的代码可在此处找到:

org.springframework.security.ui.logout.LogoutFilter

LogoutFilter调用多个处理程序.我们使用的处理程序称为: org.springframework.security.ui.logout.SecurityContextLogoutHandler,因此您可以在方法中调用相同的代码.


Pab*_*jim 8

您确实会对会话录制攻击持开放态度.为了解决这个问题,你可以再次受到Spring代码的"启发".要创建一个新会话,您显然需要访问httpsession,因此您可能需要进行一些重构.

如果你看到这个方法SessionUtils.startNewSessionIfRequired.

这会将身份验证迁移到新会话.您可以直接调用此方法,或者只是稍微重构一下代码.

至于程序化注销,只需session.invalidate()在需要将人员记录下时调用就不会出错.从一般安全角度来看,这将完成所有必要的工作,但请记住,您可能需要清理会话中的某些内容.如果您有一组非常复杂的过滤器等,并且您需要确保用户已注销剩余的请求,那么您可以添加:

SecurityContextHolder.getContext().setAuthentication(null);
Run Code Online (Sandbox Code Playgroud)

至于截取网址,你可以将它们设置为未使用的东西并忽略它!我不确定你是否可以关闭配置中的拦截 - 如果你真的想删除它然后查看AuthenticationProcessingFilter- 你可以自定义它.如果您这样做,那么您将不得不手动设置spring security xml而不使用提供的命名空间.这不是太难 - 看一些较旧的文档,你会看到如何做到这一点.

希望这可以帮助!


Gan*_*alf 6

1)程序化注销

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

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

<http ....>
  <intercept-url pattern="/myApp/**" ..>
 ....
</http>
Run Code Online (Sandbox Code Playgroud)