0
votes

I am trying to implement a function where a admin user can terminate another user's session. I followed the official Spring Security documentation here: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#list-authenticated-principals and started with getting all currently logged in users through sessionRegistry.getAllPrincipals(), but it always returned an empty list.

I set a breakpoint in SessionRegistryImpl.registerNewSession() and could see it did indeed get invoked and it did add the UserDetails (my own implementation with both equals() and hashCode() implemented) to the hashmap principals. But when I access sessionRegistry bean from a Spring MVC controller, the list is always empty.

My configuration looks pretty much the same as the documentation.

How to fix this? Did anyone successfully get SessionRegistry to work with Spring Security 4? I remember I made it work with Spring Security 3 by following these intructions(enter link description here)

1
I had the exact same problem before, and during optimization of project configuration that issue was fixed automatically for me. However, my entire configuration is for Spring-MVC and not just Spring, and is in XML. - We are Borg
Let me guess, you are loading the same configuration (classes) twice. Effectivly leading to 2 instances of all the beans including the SessionRegistry. Your controller uses a different instance as Spring Security hence it will never receive anything. Fix your configuration, make sure you aren't scanning for the components/configuraiton classes twice. - M. Deinum
Thanks all, that makes a lot of sense to me. I'll investigate the configuration first thing tomorrow, which was previously done by another person. - dnang
@M.Deinum How can I check if a bean is loaded twice ? I have the same issue with an empty list of principals. - Stephane
My spring context is explicitly loaded: <context-param> <param-name>contextConfigLocation</param-name> <param-value> WEB-INF/spring/appServlet/my-servlet-context.xml </param-value> </context-param> - Stephane

1 Answers

1
votes

OK, so I fixed the issue by cleaning up the Spring configuration files, as suggested by the comments. Someone messed up with the web.xml - he added a reference to the context XML that is already referenced by the Spring's DispatcherServlet, causing it to be loaded twice. He didn't know it, because Spring references the file implicitly.

P.S. I learned my lessons, but 2 things the Spring folks could do better (maybe in Spring 5?):

  1. There shouldn't be implicit context file loading. Currently, the framework will try to load the application context from a file named [servlet-name]-servlet.xml located in the application's WebContent/WEB-INF directory. Convention over configuration fails in this case.
  2. There should be warning when a bean is loaded twice, if someone need to override a bean definition, he must declare explicitly. Otherwise it would take a lot of time to debug the kind of error this mistake will cause.