Spring Security 的编程使用

发布于 2024-07-25 02:32:40 字数 2341 浏览 7 评论 0原文

我将 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;
}

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>

2.3.6。 参考文档的会话固定攻击防护说:

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

  • migrateSession - 创建一个新会话并复制现有会话 新会话的会话属性。 这是默认设置。
  • 无 - 不执行任何操作。 原始会话将被保留。
  • newSession - 创建一个新的“干净”会话,而不复制 现有会话数据。

身份验证有效,但由于我对 Spring Security 相当陌生,我也有一些问题需要答案:

  • 通常对于登录,我会将身份验证信息发布到 j_spring_security_check 并让 Spring Security 执行实际的身份验证代码。 我希望获得针对会话固定攻击的保护,当我像我一样执行编程登录时,我能得到它吗? 如果没有,我需要做什么才能得到它?
  • 如何执行编程注销?
  • 由于我将使用编程式登录和注销,如何禁用 Spring 拦截这些 URL?

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

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

I am using Wicket with the Wicket Auth Project for my presentation layer and I have therefore integrated it with Spring Security. This is the method which is called by Wicket for authentication for me:

@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;
}

The contents (inside ) of my Spring Security XML configuration are:

<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>

The section 2.3.6. Session Fixation Attack Protection of the reference documentation says:

Session fixation attacks are a potential risk where it is possible
for a malicious attacker to create a
session by accessing a site, then
persuade another user to log in with
the same session (by sending them a
link containing the session identifier
as a parameter, for example). Spring
Security protects against this
automatically by creating a new
session when a user logs in. If you
don't require this protection, or it
conflicts with some other requirement,
you can control the behaviour using
the session-fixation-protection
attribute on , which has three
options:

  • migrateSession - creates a new session and copies the existing
    session attributes to the new session. This is the default.
  • none - Don't do anything. The original session will be retained.
  • newSession - Create a new "clean" session, without copying the
    existing session data.

The authentication works, but I as I'm fairly new to Spring Security I have some questions which I need answers too:

  • Normally for login, I would POST the authentication information to j_spring_security_check and let Spring Security perform the actual authentication code. I would like to have protection against session fixation attacks, will I get it when I perform a programmatic login as I do? And if not, what would I have to do to get it?
  • How do I perform programmatic logout?
  • As I will use programmatic login and logout, how do I disable Spring from intercepting those URL's?

Update:
For session fixation attack protection it seems that I need to call the method in the SessionUtils class with the signature startNewSessionIfRequired(HttpServletRequest request, boolean migrateAttributes, SessionRegistry sessionRegistry).

How do I get the SessionRegistry instance which I need to pass in? I can't find any way to create an alias ID for it, or how to get it's ID or name.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

自控 2024-08-01 02:32:40

也许这不是您问题的完整答案,但也许会对您有所帮助。

当您不使用编程登录时调用的代码,但可以在这里找到标准的代码:

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

我猜您的代码中受到了这一点的启发。 看起来很相似。

类似地,当您以标准方法访问 /j_spring_security_logout 时执行的代码可以在这里找到:

org.springframework.security.ui.logout.LogoutFilter

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

Maybe it's not a full answer to your questions, but maybe it might help you.

The code being called when you do NOT use programmatic login, but a standard one is to be found here:

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

I guess you were inspired by this in your code. It looks quite similar.

Similarly the code executed when you access the /j_spring_security_logout in the standard approach, is to be found here:

org.springframework.security.ui.logout.LogoutFilter

The LogoutFilter calls multiple handlers. The handler we are using is called:
org.springframework.security.ui.logout.SecurityContextLogoutHandler, so you might call the same code in your approach.

離殇 2024-08-01 02:32:40

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

如果您看到方法 SessionUtils.startNewSessionIfRequired

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

至于程序化注销,当您需要注销该人时,只需调用 session.invalidate() 就不会犯太大的错误。 从一般安全角度来看,这将执行所有必要的操作,但请记住,尽管您可能需要清理会话中的一些内容。 如果您有一组非常复杂的过滤器等,并且需要确保用户在请求的其余部分中注销,那么您可以添加:

SecurityContextHolder.getContext().setAuthentication(null);

至于 url 的拦截,您可以将它们设置为未使用的内容并忽略它! 我不确定您是否可以在配置中关闭拦截 - 如果您确实想删除它,请查看 AuthenticationProcessingFilter - 您可以自定义它。 如果您这样做,那么您将必须手动设置 spring security xml 并且不使用提供的名称空间。 不过这并不太难——看看一些旧的文档,你就会知道如何做到这一点。

希望这可以帮助!

You will indeed be open to session fixations attacks. To remedy this you could again be "inspired" by the Spring code. To create a new session you'll obviously need access to the httpsession so you may have to do some refactoring.

If you see the method SessionUtils.startNewSessionIfRequired.

This will migrate the authentication to a new session. You might be able to call this method directly or else just refactor the code a little.

As for programmatic logout you can't go too far wrong by simply calling session.invalidate() when you need to log the person out. This will do everything necessary from a general security perspective but bear in mind though you might need to cleanup some things on the session. If you have a very complicated set of filters etc. and you need to ensure that that the user is logged out for the rest of the request then you could add:

SecurityContextHolder.getContext().setAuthentication(null);

As for interception of the url's you could just set them to something unused and ignore it! I'm not sure if you can turn off the interception in configuration - if you really want to remove it then have a look at the AuthenticationProcessingFilter - you could customise this. If you do this then you'll have to manually setup the spring security xml and not use the provided namespaces. It's not too hard though - look at some older documentation and you'll see how to do this.

Hope this helps!

不美如何 2024-08-01 02:32:40

1) 编程注销

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

2) 告诉 Spring Security 不要拦截某些 URL,这取决于您的应用程序 url 空间的设置方式。 如果您的所有页面(/logIn 和 /logout 除外)都位于上下文 /myApp 中,那么您可以这样做:

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

1) Programmatic Logout

  1. call HttpServletRequest.getSession(false).invalidate
  2. call SecurityContextHolder.clearContext()

2) Tell Spring Security NOT to intercept certain URLs, this one kind of depends on how your application url space is setup. If all your pages (except /logIn and /logout) lived at the context /myApp then you could do this:

<http ....>
  <intercept-url pattern="/myApp/**" ..>
 ....
</http>
各空 2024-08-01 02:32:40

我在程序化登录方面遇到了问题。 我调用了所有 authenticationManager.authenticate(...)SecurityContextHolder.getContext().setAuthentication(...) 方法,但会话出现了一些问题。 我必须添加以下几行才能正确管理会话:

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

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

I had an issue with programmatic login. I called all the authenticationManager.authenticate(...) and SecurityContextHolder.getContext().setAuthentication(...) methods but had some issues with the Session. I had to add the following lines to properly manage the session:

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

This was not clear from the example code posted above. For more look at http://forum.springsource.org/showthread.php?t=69761

緦唸λ蓇 2024-08-01 02:32:40

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

To do programmatic logout it's also possible to throw an org.springframework.security.core.AuthenticationException. For example, SessionAuthenticationException. In this case ExceptionTranslationFilter initiate logout.

笑脸一如从前 2024-08-01 02:32:40

你可以试试这个

    try {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }

        SecurityContextHolder.clearContext();

    } catch (Exception e) {
        logger.log(LogLevel.INFO, "Problem logging out.");
    }

You can try this

    try {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }

        SecurityContextHolder.clearContext();

    } catch (Exception e) {
        logger.log(LogLevel.INFO, "Problem logging out.");
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文