Spring security 4 防止并发登录不起作用 [英] Spring security 4 prevent concurrent login not working

查看:41
本文介绍了Spring security 4 防止并发登录不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 spring-security4 中的自定义 User 和 UserDetails 进行基于表单的用户登录.我希望防止来自同一用户的并发登录(因此该用户只能在 1 台设备上登录).

I am trying to make a form based user login with custom User and UserDetails in spring-security4. I wish to prevent concurrent logins from the same user (so the user may only be logged in on 1 device).

但是,如果我使用两个不同的浏览器,我可以在同一个用户帐户上同时使用两个浏览器登录(这是不希望的).

However if I use two different browsers, I can login with both browsers on the same user account (which is not desired).

我发现了一些类似的问题和解决方案,但不幸的是,这些解决方案在我的情况下似乎不起作用.

I found some similar problems and solutions but unfortunately the solutions didn't seem to work in my case.

请注意,我使用的是 spring-boot,所以我没有 web.xml

Please note that I am using spring-boot so I do not have a web.xml

我制作了一个如下所示的配置文件:

I made a configuration file that looks like this:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity( securedEnabled = true )
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public SecurityConfig(UserDetailsService userServ) {
        userService = userServ;
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public ServletListenerRegistrationBean<HttpSessionEventPublisher>  httpSessionEventPublisher() {
        return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher());
    }

    @Autowired
    public void configureAuth(AuthenticationManagerBuilder auth) throws Exception{
        auth
            .userDetailsService(userService)
            .passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()

            // Allow anonymous access to the static resources
            .antMatchers("/css/**").permitAll()
            .antMatchers("/font-awesome/**").permitAll()
            .antMatchers("/fonts/**").permitAll()
            .antMatchers("/img/**").permitAll()
            .antMatchers("/js/**").permitAll()

            // Need to be account admin in your business to control other accounts
            .antMatchers("/app/mybusiness/users").hasRole("ACCOUNT_ADMIN")

            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/auth/login")
            .usernameParameter("email")
            .permitAll()
            .and()
            .logout()
            .logoutSuccessUrl("/auth/login?logout")
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
            .sessionFixation()
            .migrateSession()
            .maximumSessions(1)
            .maxSessionsPreventsLogin(true);

    }

    private UserDetailsService userService;
}

提前致谢

正如你们中的一些人指出的,我忘记添加 .maxSessionsPreventsLogin(true);在我的代码中.我将此添加到我的代码中,但不幸的是没有任何改变,我仍然可以使用两个不同的浏览器(Safari 和 Firefox)使用同一个帐户登录.

As some of you pointed out I forgot to add .maxSessionsPreventsLogin(true); in my code. I added this to my code but unfortunately nothing changed, I can still login with the same account using two different browsers (Safari and Firefox).

我被要求添加启用调试的 spring 安全日志.

I was asked to add the spring security logs with DEBUG enabled.

我首先连接了 Safari 并登录了该应用程序.登录后的 spring 安全日志如下所示:

I first connected with Safari and logged in to the application. After logging in the spring security logs looked like this:

********************************************************************
**********        Security debugging is enabled.       *************
**********    This may include sensitive information.  *************
**********      Do not use in a production system!     *************
********************************************************************
2017-06-20 20:19:57.061  INFO 810 --- [  restartedMain]
o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2017-06-20 20:19:57.133  INFO 810 --- [  restartedMain] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-06-20 20:19:57.199  INFO 810 --- [  restartedMain] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-06-20 20:19:57.205  INFO 810 --- [  restartedMain] com.processbyte.PmsApplication           : Started PmsApplication in 19.414 seconds (JVM running for 19.979)
2017-06-20 20:20:01.585  INFO 810 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-06-20 20:20:01.585  INFO 810 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2017-06-20 20:20:01.600  INFO 810 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 15 ms
2017-06-20 20:20:01.609  INFO 810 --- [nio-8080-exec-1] Spring Security Debugger                 :
************************************************************
Request received for GET '/app/myaccount':
org.apache.catalina.connector.RequestFacade@e90e20
servletPath:/app/myaccount
pathInfo:null

headers: 
host: localhost:8080
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
upgrade-insecure-requests: 1
cookie: JSESSIONID=BC2B8F18111AB83F76BE3015A75B0F22
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5)     AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4
accept-language: en-us
accept-encoding: gzip, deflate
connection: keep-alive


Security filter chain: [
    WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CsrfFilter
    LogoutFilter
    UsernamePasswordAuthenticationFilter
    ConcurrentSessionFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor
]


************************************************************


2017-06-20 20:20:01.639  INFO 810 --- [nio-8080-exec-2] Spring Security    Debugger                 : 

************************************************************

Request received for GET '/auth/login':

org.apache.catalina.connector.RequestFacade@e90e20

servletPath:/auth/login
pathInfo:null
headers: 
host: localhost:8080
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
upgrade-insecure-requests: 1
cookie: JSESSIONID=BC2B8F18111AB83F76BE3015A75B0F22
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5)     AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4
accept-language: en-us
accept-encoding: gzip, deflate
connection: keep-alive


Security filter chain: [
    WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CsrfFilter
    LogoutFilter
    UsernamePasswordAuthenticationFilter
    ConcurrentSessionFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor
]


************************************************************


2017-06-20 20:21:18.862  INFO 810 --- [nio-8080-exec-5] Spring Security Debugger                 : 

************************************************************

Request received for POST '/auth/login':

org.apache.catalina.connector.RequestFacade@740e4169

servletPath:/auth/login
pathInfo:null
headers: 
host: localhost:8080
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-encoding: gzip, deflate
accept-language: en-us
content-type: application/x-www-form-urlencoded
origin: http://localhost:8080
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4
connection: keep-alive
upgrade-insecure-requests: 1
referer: http://localhost:8080/auth/login
content-length: 90
cookie: JSESSIONID=BC2B8F18111AB83F76BE3015A75B0F22


Security filter chain: [
    WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CsrfFilter
    LogoutFilter
    UsernamePasswordAuthenticationFilter
    ConcurrentSessionFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor
]


************************************************************


2017-06-20 20:21:18.891  INFO 810 --- [nio-8080-exec-5]  org.mongodb.driver.connection            : Opened connection  [connectionId{localValue:2, serverValue:7}] to localhost:27017
2017-06-20 20:21:19.103  INFO 810 --- [nio-8080-exec-3] Spring Security  Debugger                 : 

************************************************************
Request received for GET '/app/myaccount':

org.apache.catalina.connector.RequestFacade@740e4169

servletPath:/app/myaccount
pathInfo:null
headers: 
host: localhost:8080
origin: http://localhost:8080
cookie: JSESSIONID=846CA88C32032533628A31839F083F6D
connection: keep-alive
upgrade-insecure-requests: 1
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: en-us
referer: http://localhost:8080/auth/login
accept-encoding: gzip, deflate
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5)   AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4


Security filter chain: [
    WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CsrfFilter
    LogoutFilter
    UsernamePasswordAuthenticationFilter
    ConcurrentSessionFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor
]

此后,我将 Firefox 连接到相同的 URL 并使用相同的用户帐户登录,在 spring 安全日志中附加了以下内容:

Hereafter I connected with Firefox to the same URL and logged in with the same user account, the spring security log was appended with this:

2017-06-20 20:23:17.381  INFO 810 --- [nio-8080-exec-4] Spring Security Debugger                 :
************************************************************

Request received for GET '/app/myaccount':

org.apache.catalina.connector.RequestFacade@60b5387b

servletPath:/app/myaccount
pathInfo:null
headers: 
host: localhost:8080
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0)     Gecko/20100101 Firefox/53.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: en-US,en;q=0.5
accept-encoding: gzip, deflate
connection: keep-alive
upgrade-insecure-requests: 1


Security filter chain: [
    WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CsrfFilter
    LogoutFilter
    UsernamePasswordAuthenticationFilter
    ConcurrentSessionFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor
]


************************************************************

2017-06-20 20:23:17.388  INFO 810 --- [nio-8080-exec-4] Spring Security Debugger                 : 

************************************************************

New HTTP session created: 62F06B8BD67C21B90E7FE199C740767B

Call stack: 

at org.springframework.security.web.debug.Logger.info(Logger.java:44)
at org.springframework.security.web.debug.DebugRequestWrapper.getSession(DebugFilter.java:166)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at org.springframework.security.web.savedrequest.HttpSessionRequestCache.saveRequest(HttpSessionRequestCache.java:59)
at org.springframework.security.web.access.ExceptionTranslationFilter.sendStartAuthentication(ExceptionTranslationFilter.java:201)
at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException(ExceptionTranslationFilter.java:177)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:133)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:155)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.security.web.debug.DebugFilter.invokeWithWrappedRequest(DebugFilter.java:90)
at org.springframework.security.web.debug.DebugFilter.doFilter(DebugFilter.java:77)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)


************************************************************


2017-06-20 20:23:17.408  INFO 810 --- [nio-8080-exec-5] Spring Security Debugger                 : 

************************************************************

Request received for GET '/auth/login':

org.apache.catalina.connector.RequestFacade@60b5387b

servletPath:/auth/login
pathInfo:null
headers: 
host: localhost:8080
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: en-US,en;q=0.5
accept-encoding: gzip, deflate
cookie: JSESSIONID=62F06B8BD67C21B90E7FE199C740767B
connection: keep-alive
upgrade-insecure-requests: 1


Security filter chain: [
    WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CsrfFilter
    LogoutFilter
    UsernamePasswordAuthenticationFilter
    ConcurrentSessionFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor
]


************************************************************


2017-06-20 20:23:23.349  INFO 810 --- [nio-8080-exec-5] Spring Security Debugger                 : 

************************************************************

Request received for POST '/auth/login':

org.apache.catalina.connector.RequestFacade@196c2c

servletPath:/auth/login
pathInfo:null
headers: 
host: localhost:8080
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0)    Gecko/20100101 Firefox/53.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: en-US,en;q=0.5
accept-encoding: gzip, deflate
referer: http://localhost:8080/auth/login
content-type: application/x-www-form-urlencoded
content-length: 90
cookie: JSESSIONID=62F06B8BD67C21B90E7FE199C740767B
connection: keep-alive
upgrade-insecure-requests: 1


Security filter chain: [
    WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CsrfFilter
    LogoutFilter
    UsernamePasswordAuthenticationFilter
    ConcurrentSessionFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor
]


************************************************************


2017-06-20 20:23:23.504  INFO 810 --- [nio-8080-exec-7] Spring Security Debugger                 : 

************************************************************

Request received for GET '/app/myaccount':

org.apache.catalina.connector.RequestFacade@196c2c

servletPath:/app/myaccount
pathInfo:null
headers: 
host: localhost:8080
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0)    Gecko/20100101 Firefox/53.0
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language: en-US,en;q=0.5
accept-encoding: gzip, deflate
referer: http://localhost:8080/auth/login
cookie: JSESSIONID=8D8FE6BC6BEDCAB6529E30E2775817E6
connection: keep-alive
upgrade-insecure-requests: 1


Security filter chain: [
    WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CsrfFilter
    LogoutFilter
    UsernamePasswordAuthenticationFilter
    ConcurrentSessionFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor
]

推荐答案

感谢大家的回复,因为事实证明我犯了几个错误.我根据收到的反馈编辑了问题中的代码.然而,为了解决这个问题,还需要做一件事.

Thank you all for your responses, as it turned out I made several mistakes. I edited the code in my question according to the feedback I received. However there is just one more thing that needed to be done in order to solve this problem.

由于我使用了 UserDetails 的自定义实现,因此我必须覆盖 UserDetailsImpl 类中的 equals 和 hashCode.

Since I use a custom implementation of UserDetails I had to Override equals and hashCode in the UserDetailsImpl class.

@Override
public boolean equals(Object otherUser) {
    if(otherUser == null) return false;
    else if (!(otherUser instanceof UserDetails)) return false;
    else return (otherUser.hashCode() == hashCode());
}

@Override
public int hashCode() {
    return user.getEmail().hashCode() ;
}

点击此处查看来源

这篇关于Spring security 4 防止并发登录不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆