0

I have a java that calls a Servlet:

public class UserServlet extends HttpServlet {

    @Autowired
    private UserService userService;

    @Override
    protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        userService.checkUser();
        userService.doSomethingRestricted();
    }

    @Override
    public void init(final ServletConfig config) throws ServletException {
            SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
            SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
            super.init(config);
    }

}

And my autowired service :

@Component(value = "userService")
public class UserService {

    public boolean checkUser() {
        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                if (auth != null && auth.getPrincipal() != null && auth.getPrincipal() instanceof User) {
                    User springUser = (User) auth.getPrincipal();
                    if (springUser != null) {
                        LOG.debug("USER CONNECTED :: {}", springUser.getUsername());
                    }
                }
        } else {
            LOG.debug("NO CONNECTED USER, CREATING ONE");
            Collection<GrantedAuthority> authorities = getGrantedAuthorities();
            org.springframework.security.core.userdetails.User springUser = new org.springframework.security.core.userdetails.User("user","password", true, true, true, true, authorities);
            Authentication auth = new UsernamePasswordAuthenticationToken(springUser, "", authorities);
            SecurityContext sc = new SecurityContextImpl();
            sc.setAuthentication(auth);
            SecurityContextHolder.setContext(sc);
        }
        return true;
    }   


    @Secured({ "CONNECTED" })
    public void doSomethingRestricted() {
        LOG.debug("SOMETHING RESTRICTED HAS BEEN DONE!!");
    }

}
  • When I test my application the first time, the Java client sends a POST to the server, the server would check the user and would not find a context: a new context would be created.

  • When I run the java client the subsequent times, I find an existing Context (the one created in the first call).

Obviously there's something missing because If the first user logs in successfully it does not mean any user can connect.

What am I missing ? At first I thought about using sessions for each Java client's instance (I dont have web browser clients so I need to set the session ids manually), but when is Spring supposed to get or set the session id in the http request ?

TL;DR : What does SecurityContextHolder.getContext().getAuthentication() do in my example ?

Majid Laissi
  • 19,188
  • 19
  • 68
  • 105
  • See this to understand more about SecurityContextHolder [Spring security's SecurityContextHolder: session or request bound?][1] [1]: http://stackoverflow.com/questions/6408007/spring-securitys-securitycontextholder-session-or-request-bound – gouki Mar 01 '13 at 02:32

2 Answers2

2

It gets you the authentication details of the current login user , have you added

<bean id="httpSessionFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>

to introduce login for web application , spring security is designed to work with POJO as well , you would need to add this filter in your mapping if you are doing it old way. If you are using http tags in applicationContext then it should work as it is.

</security:filter-chain-map> 

Its been quite long since I have used spring security without the new http tags in applicatin Context . The spring security context comes with different filters , SecurityContextPersistenceFilter determines how the context is persisted.

"org.springframework.security.web.context.SecurityContextPersistenceFilter" is for persisting security context per session .

Spring security derived from its integration with acegi security which used to have "net.sf.acegisecurity. ui.webapp.HttpSessionIntegrationFilter" filter for the same task

Avinash Singh
  • 3,421
  • 2
  • 20
  • 21
  • thank you for the answer but i still don't get it. A Java client sends a post to the server, the server creates a context. A second Java client sends a post to the server as well, how is Spring supposed to distinguish between Client 1 (for which it created a context) and the Client 2 (who just connected for the first time) ? – Majid Laissi Mar 01 '13 at 02:04
  • `is for persisting security context per session` : what identifies a session ? how does spring tell Client 1's session is different from Client 2's session. Thank you. – Majid Laissi Mar 01 '13 at 12:28
1

It is a filter , so spring can identify session based on sessionid.

Avinash Singh
  • 3,421
  • 2
  • 20
  • 21