0

I am trying to create a Spring server for an android client and am using basic authentication. I have a controller as follows:

@RequestMapping(value = "login", method = RequestMethod.GET, produces = "application/json")
public @ResponseBody Message login(HttpSession session) {
    logger.info("Accessing protected resource sid:"+session.getId());
    return new Message(100, "Congratulations!", "You have logged in.");
}

@RequestMapping(value = "play", method = RequestMethod.GET, produces = "application/json")
public @ResponseBody Message play(HttpSession session) {
    logger.info("Accessing protected play resource");
    return new Message(100, "Congratulations!", "Launching play.");
}

Once the client has authenticated, during login, I don't want it to need to reauthenticate while calling play.

My security config is:

 protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/signup","/about").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);

        // @formatter:on
    }

}

I have tried to enable sessions above but if I try to print the session id in the request handlers in login and play, I get different ids after logging in with authentication. I am using HttpBasic security. Is it possible to have sessions in HttpBasic security? I read some articles which seemed to indicate that it is stateless and one cannot. Is there a workaround or do I have to switch to a different security model?

Client code:

On the client side, I send requests as follows for login.

@Override
    protected Message doInBackground(Void... params) {
        //final String url = getString(R.string.base_uri) + "/getmessage";
        final String url = "http://10.0.2.2:8080/login";

        // Populate the HTTP Basic Authentitcation header with the username and password
        HttpAuthentication authHeader = new HttpBasicAuthentication(username, password);
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setAuthorization(authHeader);
        requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));

        // Create a new RestTemplate instance
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());

        try {               // Make the network request
            Log.d(TAG, url);
            ResponseEntity<Message> response = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<Object>(requestHeaders), Message.class);

            if(response.getBody().getId() == 100)
                login_success = true;
            return response.getBody();

I am trying to write the client code for 'play' similarly but without the need to pass the authentication header. I feel, I should somehow pass a session related parameter in the request header to notify the server that it is part of the same session but cant figure out how to do that.

doomguy
  • 401
  • 10
  • 26
  • HTTP Basic authentication is usually stateless but doesn't have to be. Have you verified that your client is not broken? – holmis83 Jan 07 '15 at 12:48
  • Thanks. I am not currently sending any session related parameter in my requests in my client. I will think in those lines... – doomguy Jan 07 '15 at 15:59
  • @holmis83 I have updated my client code. I think I need to pass a session parameter in my header. Is this the right track? If so, then how do I get the session id here? I found this post: http://springinpractice.com/2012/04/08/sending-cookies-with-resttemplate but its not clear as to how to get the session id in the client... Could you please point me in the right direction.. – doomguy Jan 08 '15 at 16:19

1 Answers1

1

You are trying to archive stateful communication with sessions, but it won't work since RestTemplate is working in a stateless manner. It will not keep the state (i.e. the session id) from the login to the next call. Only by setting a custom ClientHttpRequestFactory I could see this work (I'm not sure on Android).

If you want communication with state, you could look at Apache HttpClient. By using it with a HttpContext that you re-use between requests, it will keep the state.

There is a possibility to fiddle with the session id yourself, but I can't recommend it.

holmis83
  • 15,922
  • 5
  • 82
  • 83
  • Thanks, I will try the HttpClient approach. – doomguy Jan 08 '15 at 19:57
  • Thanks. I tried the approach with the reused httpcontext and it works. Could you please elaborate briefly as to why the session id tracking is not recommended? Does it have to do with session fixation attacks? – doomguy Jan 11 '15 at 05:23
  • @doomguy What I meant was that you shouldn't work on that level when there's a library doing it for you, because reinventing the wheel is error-prone. – holmis83 Jan 11 '15 at 09:07