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;
}
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>
会话固定攻击是一种潜在风险 以便恶意攻击者创建 通过访问站点进行会话,然后 说服其他用户登录 同一会话(通过向他们发送 包含会话标识符的链接 例如作为参数)。 春天 安全性可以防止这种情况 通过创建新的自动 用户登录时的会话。如果您 不需要这种保护,或者它 与其他一些要求相冲突, 你可以使用控制行为 会话固定保护 属性 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
也许这不是您问题的完整答案,但也许会对您有所帮助。
当您不使用编程登录时调用的代码,但可以在这里找到标准的代码:
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.您确实会对会话固定攻击持开放态度。 为了解决这个问题,您可以再次受到 Spring 代码的“启发”。 要创建新会话,您显然需要访问 httpssession,因此您可能需要进行一些重构。
如果您看到方法
SessionUtils
.startNewSessionIfRequired
。这会将身份验证迁移到新会话。 您也许可以直接调用此方法,或者只需稍微重构一下代码即可。
至于程序化注销,当您需要注销该人时,只需调用
session.invalidate()
就不会犯太大的错误。 从一般安全角度来看,这将执行所有必要的操作,但请记住,尽管您可能需要清理会话中的一些内容。 如果您有一组非常复杂的过滤器等,并且需要确保用户在请求的其余部分中注销,那么您可以添加:至于 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: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!
1) 编程注销
2) 告诉 Spring Security 不要拦截某些 URL,这取决于您的应用程序 url 空间的设置方式。 如果您的所有页面(/logIn 和 /logout 除外)都位于上下文 /myApp 中,那么您可以这样做:
1) Programmatic Logout
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:
我在程序化登录方面遇到了问题。 我调用了所有
authenticationManager.authenticate(...)
和SecurityContextHolder.getContext().setAuthentication(...)
方法,但会话出现了一些问题。 我必须添加以下几行才能正确管理会话:从上面发布的示例代码中并不清楚这一点。 有关更多信息,请参阅 http://forum.springsource.org/showthread.php?t=69761
I had an issue with programmatic login. I called all the
authenticationManager.authenticate(...)
andSecurityContextHolder.getContext().setAuthentication(...)
methods but had some issues with the Session. I had to add the following lines to properly manage the session:This was not clear from the example code posted above. For more look at http://forum.springsource.org/showthread.php?t=69761
要以编程方式注销,也可以抛出 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 caseExceptionTranslationFilter
initiate logout.你可以试试这个
You can try this