3

I'm trying to do rest login from an android app to a web backend. In my web application:

I have this class extending BasicAuthenticationEntryPoint:

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;

public class CustomBasicAuthenticationEntryPoint extends
        BasicAuthenticationEntryPoint {

    @Override
    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
        super.afterPropertiesSet();
    }

    @Override
    public void commence(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {
        response.setHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.getOutputStream().println("{\"responseCode\":\"FAILED\"}");
        response.getOutputStream().flush();
        //super.commence(request, response, authException);
    }

Then I have this class extending BasicAuthenticationFilter:

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.stereotype.Component;

@Component("customBasicAuthFilter")
public class CustomBasicAuthFilter extends BasicAuthenticationFilter {

    @Autowired
    public CustomBasicAuthFilter(AuthenticationManager authenticationManager)
    {
        super(authenticationManager);
    }

    @Override
    protected void onSuccessfulAuthentication(HttpServletRequest request,
            HttpServletResponse response, Authentication authResult)
            throws IOException {
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        super.onSuccessfulAuthentication(request, response, authResult);
    }
}

This is the configuration:

<security:http realm="appApi" pattern="/rest/**" entry-point-ref="restAuthenticationEntryPoint" create-session="stateless">
    <security:custom-filter ref="customBasicAuthFilter" position="BASIC_AUTH_FILTER"/>
</security:http>
<bean id="customBasicAuthFilter" class="org.springtest.mavenspringapp.service.CustomBasicAuthFilter"></bean>

<bean id="restAuthenticationEntryPoint" class="org.springtest.mavenspringapp.service.CustomBasicAuthenticationEntryPoint">
    <property name="realmName" value="appApi"></property>
</bean>

My controller looks like this:

@Controller
@RequestMapping(value = "/rest")
public class RestController {


    /************** AJAX Methods ****************/
    @RequestMapping(value = "/login/", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody String ajaxLogin(HttpServletRequest request, HttpServletResponse response)
    {
        return "Success";
    }
}

The android code trying to do rest login is the one below:

public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
        @Override
        protected Boolean doInBackground(Void... params) {
            // TODO: attempt authentication against a network service.
            //boolean success = JSONAuthenticationHandler.JSONAuthenticationResult(mEmail, mPassword);
            HttpAuthentication authHeader = new HttpBasicAuthentication(mEmail, mPassword);
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.setAuthorization(authHeader);
            requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
            requestHeaders.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);

            RestTemplate restTemplate = new RestTemplate();
            restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());

            try
            {
                ResponseEntity<String> response = restTemplate.exchange(    "http://192.168.1.12:8080/mavenspringapp/rest/login/", 
                                                                            HttpMethod.GET, 
                                                                            new HttpEntity<Object>(requestHeaders), 
                                                                            String.class);
                String loginResult = response.getBody();

                return true;
            }
            catch (HttpClientErrorException ex)
            {
                return false;
            }
            catch (ResourceAccessException ex)
            {
                return false;
            }
            catch (Exception ex)
            {
                ex.getCause();
                return false;
            }
        }
}

I'm debugging both applicatios (Eclipse ADT and Spring Toolsuite). According to documentations I read about spring security, commence is invoked when authentication fails but I placed a breakpoint in my method and is never executed and even worse, the controller is executed and returns the string success.

Am I misunderstanding the way spring security works or is there something missing? Please help. Thanks in advance.

Jorge Cespedes
  • 547
  • 1
  • 11
  • 21

0 Answers0