Java Spring Security 的编程使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1013032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatic use of Spring Security
提问by
I am using Wicketwith 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:
我将Wicket与 Wicket Auth Project 用于我的表示层,因此我已将其与 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;
}
The contents (inside ) of my Spring Security XML configuration are:
我的 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>
The section 2.3.6. Session Fixation Attack Protectionof the reference documentation says:
第2.3.6节。参考文档的Session Fixation Attack Protection说:
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.
会话固定攻击是一种潜在风险,恶意攻击者有可能通过访问站点来创建会话,然后说服另一个用户使用同一会话登录(通过向他们发送包含会话标识符作为参数的链接,对于例子)。Spring Security 通过在用户登录时创建一个新会话来自动防止这种情况。如果您不需要这种保护,或者它与其他一些要求冲突,您可以使用 session-fixation-protection 属性来控制行为,它有三个选项:
- migrateSession - 创建一个新会话并将现有会话属性复制到新会话。这是默认设置。
- none - 什么都不做。原始会话将被保留。
- newSession - 创建一个新的“干净”会话,而不复制现有的会话数据。
The authentication works, but I as I'm fairly new to Spring Security I have some questions which I need answers too:
身份验证有效,但由于我对 Spring Security 还很陌生,所以我也有一些问题需要回答:
- 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?
- 通常对于登录,我会将身份验证信息 POST 到
j_spring_security_check
并让 Spring Security 执行实际的身份验证代码。我想要防止会话固定攻击,当我像我一样执行程序化登录时,我会得到它吗?如果没有,我需要做什么才能得到它? - 如何执行程序化注销?
- 由于我将使用程序化登录和注销,我如何禁用 Spring 拦截这些 URL?
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)
.
更新:对于会话固定攻击保护,似乎我需要使用签名调用 SessionUtils 类中的方法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.
如何获取需要传入的 SessionRegistry 实例?我找不到任何方法来为它创建别名 ID,或者如何获取它的 ID 或名称。
采纳答案by Grzegorz Oledzki
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
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:
类似地/j_spring_security_logout
,在标准方法中访问 时执行的代码可在此处找到:
org.springframework.security.ui.logout.LogoutFilter
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.
LogoutFilter 调用多个处理程序。我们正在使用的处理程序称为:
org.springframework.security.ui.logout.SecurityContextLogoutHandler
,因此您可以在您的方法中调用相同的代码。
回答by Pablojim
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.
您确实会对会话固定攻击持开放态度。为了解决这个问题,您可以再次受到 Spring 代码的“启发”。要创建一个新会话,您显然需要访问 httpsession,因此您可能需要进行一些重构。
If you see the method SessionUtils
.startNewSessionIfRequired
.
如果你看到方法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:
至于程序化注销,您只需session.invalidate()
在需要注销此人时调用,就不会出错。从一般安全角度来看,这将完成所有必要的操作,但请记住,尽管您可能需要清理会话中的某些内容。如果您有一组非常复杂的过滤器等,并且您需要确保用户在请求的其余部分已注销,那么您可以添加:
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.
至于拦截网址,您可以将它们设置为未使用的内容并忽略它!我不确定您是否可以在配置中关闭拦截-如果您真的想删除它,请查看AuthenticationProcessingFilter
-您可以自定义它。如果这样做,则必须手动设置 spring 安全性 xml,而不是使用提供的命名空间。不过这并不太难 - 查看一些较旧的文档,您将了解如何执行此操作。
Hope this helps!
希望这可以帮助!
回答by Gandalf
1) Programmatic Logout
1) 程序化注销
- call HttpServletRequest.getSession(false).invalidate
- call SecurityContextHolder.clearContext()
- 调用 HttpServletRequest.getSession(false).invalidate
- 调用 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:
2) 告诉 Spring Security 不要拦截某些 URL,这取决于您的应用程序 url 空间是如何设置的。如果您的所有页面(/logIn 和 /logout 除外)都位于上下文 /myApp 中,那么您可以执行以下操作:
<http ....>
<intercept-url pattern="/myApp/**" ..>
....
</http>
回答by viator
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.
要进行程序化注销,也可以抛出org.springframework.security.core.AuthenticationException
. 例如,SessionAuthenticationException
。在这种情况下ExceptionTranslationFilter
启动注销。
回答by velaia
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:
我遇到了程序化登录的问题。我调用了所有的authenticationManager.authenticate(...)
和SecurityContextHolder.getContext().setAuthentication(...)
方法,但是 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
从上面发布的示例代码中并不清楚这一点。有关更多信息,请访问http://forum.springsource.org/showthread.php?t=69761
回答by Chandra
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.");
}