Re: [android-developers] Android Client Authentication with Spring Security 3

2011-08-05 Thread Daniel Drozdzewski
Kevin,

You are right - pure REST service should be stateless.
But as usual, life is not just black or white and there is lots of
room for 'less pure' services.

Technically cookie is a part of each request, so you are
authenticating with every call, but using session token instead of
user credentials.
Without using cookies in this example, you would be storing username
and password to send with each request anyway.

One could argue that keeping disposable session token that expires is
safer than keeping username and password, which by their nature have
longer life expectancies, therefore security around them should be
tighter and cookies offer exactly that.

I understand that from service scalability point of view, session-less
solution would be easier to scale up.

As usual it is a judgement call and that's it.


Daniel








On 4 August 2011 20:25, Kevin Duffey andjar...@gmail.com wrote:
 I am wondering why you are making a call to a rest service and trying to
 keep state? Rest calls typically are stateless. You should pass the
 credentials each time and the rest service should validate those credentials
 each time. By storing a cookie you end up having to keep track of timeouts..
 what happens in your android app when the cookie expires and you make a
 request again and it fails due to the cookie being bad? Are you going to ask
 the user to enter their credentials again? You might be better off storing
 the entered credentials and sending them on every request. Also, did you
 write the service? If so, why are you issuing a cookie? Why not just have
 the service check for credentials every time?

 On Thu, Aug 4, 2011 at 5:45 AM, Daniel Drozdzewski
 daniel.drozdzew...@gmail.com wrote:

 On 4 August 2011 13:27, Asuka c.bau...@gmx.de wrote:
  Hi Android Developers,
 
  I try to connect to a webapplication via my android client. In the
  webapplication we use spring security 3 to login. The relevant part of
  the login configuration looks like this:
 
  security:http auto-config='true' access-denied-page=/
  accessDenied.html
                 security:intercept-url pattern=/**
  access=ROLE_STANDARD /
                 security:form-login login-page=/login.html
                         authentication-failure-url=/login_error.html
  default-target-url=/
  pages/start/start.html
                         always-use-default-target=true /
                         security:remember-me key=xxx
  token-validity-seconds=3 data-
  source-ref=dataSource/
 
                 security:logout logout-success-url=/login.html
                         invalidate-session=false /
                 security:session-management
                 security:concurrency-control max-sessions=1 /
             /security:session-management
         /security:http
 
  So that means, the webapp is able to remember the user. From the
  android client I call a webservice:
 
  public void onLogin(final View v) {
 
                 EditText username = (EditText)
  findViewById(R.id.editusername);
                 EditText password = (EditText)
  findViewById(R.id.editpassword);
                 client = new DefaultHttpClient();
                 String getToken = ;
 
                 // Call Webservice
                 HttpPost loginRequest = new
  HttpPost(PathContainer.baseWebservice
  +login?);
                 ResponseHandlerString respstring = new
  BasicResponseHandler();
 
                         try {
                                 JSONObject credentials = new
  JSONObject();
                                 try {
 
   credentials.put(name,username.getEditableText().toString());
 
  credentials.put(password,password.getEditableText().toString());
                                 } catch (JSONException e1) {
                                         e1.printStackTrace();
                                 }
                                 StringEntity seUser = new
  StringEntity(credentials.toString(),
  UTF-8);
                                 loginRequest.setEntity(seUser);
                                 getToken = client.execute(loginRequest,
  respstring);
                         if (getToken != null) {
                                 if (getToken.startsWith(token)) {
                                         String[]t= getToken.split(:);
                                         securtiytoken=t[1];
                                         Cursor token=
  getContentResolver().query(URI, null, null, null,
  null);
                                         if(token.getCount()==0){
                                                 insertTokenIntoDB(this,
  securtiytoken,username.getEditableText().toString());
                                         }else{
                                                 updateToken(this,
  securtiytoken,username.getEditableText().toString());
                                         }
                                         token.close();
                                         this.startMain();
 

[android-developers] Android Client Authentication with Spring Security 3

2011-08-04 Thread Asuka
Hi Android Developers,

I try to connect to a webapplication via my android client. In the
webapplication we use spring security 3 to login. The relevant part of
the login configuration looks like this:

security:http auto-config='true' access-denied-page=/
accessDenied.html
security:intercept-url pattern=/** access=ROLE_STANDARD /
security:form-login login-page=/login.html
authentication-failure-url=/login_error.html 
default-target-url=/
pages/start/start.html
always-use-default-target=true /
security:remember-me key=xxx 
token-validity-seconds=3 data-
source-ref=dataSource/

security:logout logout-success-url=/login.html
invalidate-session=false /
security:session-management
security:concurrency-control max-sessions=1 /
/security:session-management
/security:http

So that means, the webapp is able to remember the user. From the
android client I call a webservice:

public void onLogin(final View v) {

EditText username = (EditText)
findViewById(R.id.editusername);
EditText password = (EditText) findViewById(R.id.editpassword);
client = new DefaultHttpClient();
String getToken = ;

// Call Webservice
HttpPost loginRequest = new 
HttpPost(PathContainer.baseWebservice
+login?);
ResponseHandlerString respstring = new BasicResponseHandler();

try {
JSONObject credentials = new JSONObject();
try {

credentials.put(name,username.getEditableText().toString());

credentials.put(password,password.getEditableText().toString());
} catch (JSONException e1) {
e1.printStackTrace();
}
StringEntity seUser = new 
StringEntity(credentials.toString(),
UTF-8);
loginRequest.setEntity(seUser);
getToken = client.execute(loginRequest, 
respstring);
if (getToken != null) {
if (getToken.startsWith(token)) {
String[]t= getToken.split(:);
securtiytoken=t[1];
Cursor token= 
getContentResolver().query(URI, null, null, null,
null);
if(token.getCount()==0){
insertTokenIntoDB(this,
securtiytoken,username.getEditableText().toString());
}else{
updateToken(this,
securtiytoken,username.getEditableText().toString());
}
token.close();
this.startMain();
}else{
Toast.makeText(this,Anmeldung 
fehlgeschlagen ...
,Toast.LENGTH_LONG).show();
this.loginAgain();
}
}
} catch (ClientProtocolException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}

The webservice looks like this

@POST
@Produces(MediaType.TEXT_PLAIN)
@Path(/login)
public String login(String credentials) {
JSONObject jo = null;
String name = ;
String password = ;
try {
jo = new JSONObject(credentials);
name = jo.getString(name);
password = jo.getString(password);
} catch (JSONException e) {
e.printStackTrace();
}
HttpResponse r = springSecurityCheck(name, password);
for (Header h : r.getAllHeaders()) {
System.out.println(h.getName() +   +   + h.getValue() +
);
}

String s = r.getFirstHeader(Location).toString();
boolean isError = s.contains(login_error);

if (!isError) {
Header[] cookies = r.getHeaders(Set-Cookie);
for (int i = 0; i  cookies.length; i++) {
if (cookies[i].toString().contains(
SPRING_SECURITY_REMEMBER_ME_COOKIE)) {
String[] cookie = cookies[i].toString().split(=);
String token = cookie[1].substring(0,
cookie[1].indexOf(;));
if (token != null) {
return token: + token;
}
}
}
}
System.out.println( - Login from + name
+  failed- );
return newLogin;

}

After the login, a 

Re: [android-developers] Android Client Authentication with Spring Security 3

2011-08-04 Thread Daniel Drozdzewski
On 4 August 2011 13:27, Asuka c.bau...@gmx.de wrote:
 Hi Android Developers,

 I try to connect to a webapplication via my android client. In the
 webapplication we use spring security 3 to login. The relevant part of
 the login configuration looks like this:

 security:http auto-config='true' access-denied-page=/
 accessDenied.html
                security:intercept-url pattern=/** access=ROLE_STANDARD /
                security:form-login login-page=/login.html
                        authentication-failure-url=/login_error.html 
 default-target-url=/
 pages/start/start.html
                        always-use-default-target=true /
                        security:remember-me key=xxx 
 token-validity-seconds=3 data-
 source-ref=dataSource/

                security:logout logout-success-url=/login.html
                        invalidate-session=false /
                security:session-management
                security:concurrency-control max-sessions=1 /
            /security:session-management
        /security:http

 So that means, the webapp is able to remember the user. From the
 android client I call a webservice:

 public void onLogin(final View v) {

                EditText username = (EditText)
 findViewById(R.id.editusername);
                EditText password = (EditText) findViewById(R.id.editpassword);
                client = new DefaultHttpClient();
                String getToken = ;

                // Call Webservice
                HttpPost loginRequest = new 
 HttpPost(PathContainer.baseWebservice
 +login?);
                ResponseHandlerString respstring = new 
 BasicResponseHandler();

                        try {
                                JSONObject credentials = new JSONObject();
                                try {
                                        
 credentials.put(name,username.getEditableText().toString());

 credentials.put(password,password.getEditableText().toString());
                                } catch (JSONException e1) {
                                        e1.printStackTrace();
                                }
                                StringEntity seUser = new 
 StringEntity(credentials.toString(),
 UTF-8);
                                loginRequest.setEntity(seUser);
                                getToken = client.execute(loginRequest, 
 respstring);
                        if (getToken != null) {
                                if (getToken.startsWith(token)) {
                                        String[]t= getToken.split(:);
                                        securtiytoken=t[1];
                                        Cursor token= 
 getContentResolver().query(URI, null, null, null,
 null);
                                        if(token.getCount()==0){
                                                insertTokenIntoDB(this,
 securtiytoken,username.getEditableText().toString());
                                        }else{
                                                updateToken(this,
 securtiytoken,username.getEditableText().toString());
                                        }
                                        token.close();
                                        this.startMain();
                                }else{
                                        Toast.makeText(this,Anmeldung 
 fehlgeschlagen ...
 ,Toast.LENGTH_LONG).show();
                                        this.loginAgain();
                                }
                        }
                } catch (ClientProtocolException e1) {
                        e1.printStackTrace();
                } catch (IOException e1) {
                        e1.printStackTrace();
                }
        }

 The webservice looks like this

 @POST
 @Produces(MediaType.TEXT_PLAIN)
 @Path(/login)
 public String login(String credentials) {
    JSONObject jo = null;
    String name = ;
    String password = ;
    try {
        jo = new JSONObject(credentials);
        name = jo.getString(name);
        password = jo.getString(password);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    HttpResponse r = springSecurityCheck(name, password);
    for (Header h : r.getAllHeaders()) {
        System.out.println(h.getName() +   +   + h.getValue() +
 );
    }

    String s = r.getFirstHeader(Location).toString();
    boolean isError = s.contains(login_error);

    if (!isError) {
        Header[] cookies = r.getHeaders(Set-Cookie);
        for (int i = 0; i  cookies.length; i++) {
            if (cookies[i].toString().contains(
                    SPRING_SECURITY_REMEMBER_ME_COOKIE)) {
                String[] cookie = cookies[i].toString().split(=);
                String token = cookie[1].substring(0,
                        cookie[1].indexOf(;));
                if (token != null) {
                    return token: + token;
                }
            }
        }
    }
    System.out.println( - Login from + name
            

Re: [android-developers] Android Client Authentication with Spring Security 3

2011-08-04 Thread Kevin Duffey
I am wondering why you are making a call to a rest service and trying to
keep state? Rest calls typically are stateless. You should pass the
credentials each time and the rest service should validate those credentials
each time. By storing a cookie you end up having to keep track of timeouts..
what happens in your android app when the cookie expires and you make a
request again and it fails due to the cookie being bad? Are you going to ask
the user to enter their credentials again? You might be better off storing
the entered credentials and sending them on every request. Also, did you
write the service? If so, why are you issuing a cookie? Why not just have
the service check for credentials every time?

On Thu, Aug 4, 2011 at 5:45 AM, Daniel Drozdzewski 
daniel.drozdzew...@gmail.com wrote:

 On 4 August 2011 13:27, Asuka c.bau...@gmx.de wrote:
  Hi Android Developers,
 
  I try to connect to a webapplication via my android client. In the
  webapplication we use spring security 3 to login. The relevant part of
  the login configuration looks like this:
 
  security:http auto-config='true' access-denied-page=/
  accessDenied.html
 security:intercept-url pattern=/**
 access=ROLE_STANDARD /
 security:form-login login-page=/login.html
 authentication-failure-url=/login_error.html
 default-target-url=/
  pages/start/start.html
 always-use-default-target=true /
 security:remember-me key=xxx
 token-validity-seconds=3 data-
  source-ref=dataSource/
 
 security:logout logout-success-url=/login.html
 invalidate-session=false /
 security:session-management
 security:concurrency-control max-sessions=1 /
 /security:session-management
 /security:http
 
  So that means, the webapp is able to remember the user. From the
  android client I call a webservice:
 
  public void onLogin(final View v) {
 
 EditText username = (EditText)
  findViewById(R.id.editusername);
 EditText password = (EditText)
 findViewById(R.id.editpassword);
 client = new DefaultHttpClient();
 String getToken = ;
 
 // Call Webservice
 HttpPost loginRequest = new
 HttpPost(PathContainer.baseWebservice
  +login?);
 ResponseHandlerString respstring = new
 BasicResponseHandler();
 
 try {
 JSONObject credentials = new JSONObject();
 try {
 
  credentials.put(name,username.getEditableText().toString());
 
  credentials.put(password,password.getEditableText().toString());
 } catch (JSONException e1) {
 e1.printStackTrace();
 }
 StringEntity seUser = new
 StringEntity(credentials.toString(),
  UTF-8);
 loginRequest.setEntity(seUser);
 getToken = client.execute(loginRequest,
 respstring);
 if (getToken != null) {
 if (getToken.startsWith(token)) {
 String[]t= getToken.split(:);
 securtiytoken=t[1];
 Cursor token=
 getContentResolver().query(URI, null, null, null,
  null);
 if(token.getCount()==0){
 insertTokenIntoDB(this,
  securtiytoken,username.getEditableText().toString());
 }else{
 updateToken(this,
  securtiytoken,username.getEditableText().toString());
 }
 token.close();
 this.startMain();
 }else{
 Toast.makeText(this,Anmeldung
 fehlgeschlagen ...
  ,Toast.LENGTH_LONG).show();
 this.loginAgain();
 }
 }
 } catch (ClientProtocolException e1) {
 e1.printStackTrace();
 } catch (IOException e1) {
 e1.printStackTrace();
 }
 }
 
  The webservice looks like this
 
  @POST
  @Produces(MediaType.TEXT_PLAIN)
  @Path(/login)
  public String login(String credentials) {
 JSONObject jo = null;
 String name = ;
 String password = ;
 try {
 jo = new JSONObject(credentials);
 name = jo.getString(name);
 password = jo.getString(password);
 } catch (JSONException e) {
 e.printStackTrace();
 }