shoaib
shoaib

Reputation: 175

How to Authenticate user using Android/IOs apps with Spring security through json response/request

I am having server side (back end) code in spring MVC rest full web service. Now I have an app (android/IOs) where user can register him self to access the different features and its all working fine through JSON response and request. But now I want to authenticate user using an login fields in the app. how can I authenticate the user.

As till now what I have search we can do it by form authentication using spring security. but the mobile app doesn't have the form and more over the login credentials that I will be getting is in JSON format then how the authentication will happen. So, how can I authenticate user from android/IOs app with spring security with data in JSON format

Upvotes: 3

Views: 4491

Answers (1)

Rob Winch
Rob Winch

Reputation: 21720

My suggestion is to checkout the Spring Session REST guide. Below are the highlights.

I'd suggest using HTTP Basic to submit your credentials. This can be done in spring security with the following Java Configuration:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // @formatter:off
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .requestCache()
                .requestCache(new NullRequestCache())
                .and()
            .httpBasic();
    }
    // @formatter:on

    // @formatter:off
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
    // @formatter:on
}

Then expose your user object via a rest endpoint

// NOTE could replace Principal w/ Spring Security's Authentication object too
// Just be careful you don't expose the password over REST!
@RequestMapping(value="/user",produces = "application/json")
public Map<String,String> helloUser(Principal principal) {
    HashMap<String,String> result = new HashMap<String,String>();
    result.put("username", principal.getName());
    return result;
}

Now you can submit the username / password using basic authentication. For example with curl:

curl -v http://localhost:8080/ -u user:password

HTTP/1.1 200 OK
...
Set-Cookie: JSESSIONID=0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3; ...

{"username":"user"}

The problem is that cookies are really intended for a browser. It also makes it difficult to cluster your application. Enter Spring Session.

Spring Session allows you to easily back your HttpSession using Redis or other arbitrary data stores. To use it, first create the Spring Session Filter:

@Configuration
@EnableRedisHttpSession 
public class HttpSessionConfig {

        // this will hit redis on localhost and the default port
        @Bean
        public JedisConnectionFactory connectionFactory() {
                JedisConnectionFactory factory = new JedisConnectionFactory();  
                // ... customize ...
                return factory;
        }

        // override the default of using cookies and instead use headers
        @Bean
        public HttpSessionStrategy httpSessionStrategy() {
                return new HeaderHttpSessionStrategy(); 
        }
}

Then ensure to add Spring Session's SessionRepositoryFilter to your container. For example, in a subclass of AbstractAnnotationConfigDispatcherServletInitializer ensure your configuration is loaded in the root context:

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[] {SecurityConfig.class, HttpSessionConfig.class};
}

Next, create a subclass of AbstractHttpSessionApplicationInitializer to register the SessionRepositoryFilter for all requests. For example:

public class Initializer extends AbstractHttpSessionApplicationInitializer {

}

Now you can do this:

curl -v http://localhost:8080/ -u user:password

HTTP/1.1 200 OK
...
x-auth-token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3; ...

{"username":"user"}

The header can now be used to make additional requests:

curl -v http://localhost:8080/messages/ -H "x-auth-token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3"

For additional information (including XML based configuration), refer to the Spring Session documentation.

Upvotes: 6

Related Questions