我正在使用spring security来实现程序化的手动用户登录。我有一个场景,我已经积极建立用户的身份,并希望登录。我不知道他们的密码,所以不能使用常规登录代码路径,你提交表单到网址,春天通过servlet Filter
拦截,完成所有的auth +会话魔法。
我已经搜索过,似乎大多数人都会创建自己的Authentication
对象,然后通过以下方式告诉spring:
PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(user, "", user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
确实,这很有效。 Spring甚至将它放入会话中,使后续的http请求保持其身份验证状态。
然而,我觉得这是一个肮脏的黑客。我将提供一些细节,希望能给出在控制器中使用setAuthentication()
来实现手动登录的相关问题的具体示例:
要提出一个想法,我的配置是:
httpSecurity
.authorizeRequests()
.antMatchers("/test/**").permitAll()
.antMatchers("/admin/**", "/api/admin/**").hasRole("USER_SUPER_ADMIN")
.and()
.formLogin()
.loginPage("/sign-in?sp")
.loginProcessingUrl("/api/auth/sign-in")
.successHandler(createLoginSuccessHandler())
.failureHandler(createLoginFailureHandler())
.permitAll()
.and()
.logout()
.logoutUrl("/api/auth/sign-out")
.logoutSuccessHandler(createLogoutSuccessHandler())
.and()
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry)
;
以上要点:
- 我使用自定义成功和失败处理程序进行表单登录
- 我想为每个用户的最大并发会话配置行为
- 我想保持spring的默认会话固定保护(登录时更改会话ID)
- 我想使用会话注册表
- ...更多,如果我选择配置它。
我逐步完成了代码,看看spring如何处理表单登录。正如预期的那样,当我使用表单登录时,Spring会执行我的HttpSecurity
配置要求它执行的所有操作。但是,当我通过SecurityContextHolder.getContext().setAuthentication()
进行我自己的自定义/手动登录时,它没有做到这一点。这是因为spring在servlet Filter
中完成了所有的auth + session事务,而我的编程代码实际上无法调用Filter。现在,我可以尝试自己添加丢失的行为,复制他们的代码:我看到过滤器使用:ConcurrentSessionControlAuthenticationStrategy
,ChangeSessionIdAuthenticationStrategy
和RegisterSessionAuthenticationStrategy
。我可以自己创建这些对象,配置它们,并在我的自定义登录后调用它们。但是,以这种方式复制它有点蹩脚。此外,我还缺少其他行为 - 我注意到当使用表单登录代码路径时,该弹簧会触发一些登录事件,这些事件在我进行自定义登录时不会被触发。而且可能还有其他我缺少或不理解的东西。整个过程非常复杂。
所以,我觉得我是从错误的方式接近这个。 我是否应该使用不同的策略,以便我不会绕过春天为我做的那么多东西?也许我应该尝试自己AuthenticationProvider
来完成这个习惯登录资讯?
*为了澄清,我的代码或多或少有效。但是,我觉得我是用一种糟糕的策略来完成它的,因为我必须编写代码来复制很多春天给我的东西。此外,我的代码并没有完全复制Spring的功能,让我想知道可能会产生什么负面影响。必须有一种更好的方式来以编程方式实现登录。
答案 0 :(得分:1)
对于自定义Web身份验证,您应该实现自定义身份验证筛选器(例如AbstractAuthenticationProcessingFilter
或仅GenericFilterBean
),自定义身份验证提供程序(AuthenticationProvider
)或/和自定义身份验证令牌的组合(AbstractAuthenticationToken
)。
例如,请参阅Spring Security Kerberos的来源。
另见: