14

I am making an android app using Retrofit 2. My REST Api are all written in Liferay. Now in Liferay, what I have seen is, to access the web services we need to authenticate first. So i have authenticated like this

http://test:q1w2e3r4@192.168.0.110:8080/liferay-portlet/api/secure/jsonws/

Liferay has its own user authentication method which we have overridden.I checked the Web service call from Postman its working fine.

URL:http://test:q1w2e3r4@192.168.0.110:8080/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name

form-encoded values

companyId:10154
screenName:xyz
password:xyz
active:true

If i put this in the postman, it fetches the json response properly.

Now when i call the same from my android code i get a response "Unauthorized".

My Retrofit service

public interface LoginApi {    
    @FormUrlEncoded
    @POST("/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name")
    Call<User> login(@Field("companyId")long companyId,@Field("screenName")String screenName,@Field("password")String password,@Field("active")boolean active);
}

My RestApiManager Class(This class is used to call the service interface and create the retrofit builder)

public class RestApiManager {

    private LoginApi loginApi;

    public LoginApi login() {
        if (loginApi==null) {
            GsonBuilder gson=new GsonBuilder();
            gson.registerTypeAdapter(String.class, new StringDeserializer());
            Retrofit retrofit=new Retrofit.Builder()
                .baseUrl("http://test:q1w2e3r4@192.168.0.110:8080")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
            loginApi=retrofit.create(LoginApi.class);
    }
    return loginApi;
}

A call to the RestApiManager

Call<User> callUser=restApiManager.login().login(loginData.getCompanyId(),loginData.getScreenName(),loginData.getPassword(),loginData.isActive());
callUser.enqueue(new Callback<User>() {
    @Override
    public void onResponse(Response<User> response, Retrofit retrofit) {
        Log.d("Login","Login Response:"+response.body());
    }

    @Override
    public void onFailure(Throwable t) {
        Log.d("Login","Login Response:"+t.getMessage());
    }
});
iagreen
  • 31,470
  • 8
  • 76
  • 90
Deb
  • 2,431
  • 3
  • 18
  • 28

5 Answers5

5

It looks like perhaps your request should have a JSON body instead of a POST variables? You are calling a JSON webservice and your example parameters look more JSON than POST. If so, then you can encapsulate your parameters in an object --

public class User {
    int companyId;
    String screenName;
    String password;
    boolean active;

    User(int companyId, String screenName, String password, boolean active) {
        this.companyId = companyId;
        this.screenName = screenName;
        this.password = password;
        this.active = active;
}

Your interface would be --

public interface LoginApi {    
    @POST("/liferay-portlet/api/secure/jsonws/customuserauthentication/authenticate-by-user-name")
    Call<User> login(@Body User user);
}

and construct your call as --

User user = new User(loginData.getCompanyId(),loginData.getScreenName(),loginData.getPassword(),loginData.isActive());
Call<User> callUser = restApiManager.login().login(user);
iagreen
  • 31,470
  • 8
  • 76
  • 90
1

The session management in cross-platform does not work the way it works on browser. Postman is a web client that works on browser platform.

1.One solution is to maintain cookies on the device.

Check this answer manage sessions with Android Application.

2.The other solution would be to use Json Web Token based auth.

Community
  • 1
  • 1
harsh_v
  • 3,193
  • 3
  • 34
  • 53
1

I tried to run your demo code in my local PC, but no lucky as your server is in your local area network, about this question if you are using cookie or session authorize in you server side, I would suggestion you try to setCookieHandler as following, the PersistentCookieStore.java you can find here

private PersistentCookieStore cookieStore= new PersistentCookieStore(JApplication.getInstance().getApplicationContext());
CookieManager cookieManager = (new CookieManager(
            cookieStore,
            CookiePolicy.ACCEPT_ALL));

okHttpClient.setCookieHandler(cookieManager);
OkClient okClient = new OkClient(okHttpClient);
RestAdapter restAdapter = new RestAdapter.Builder()
            .setRequestInterceptor(new RequestInterceptor() {
                @Override
                public void intercept(RequestFacade request) {
                    request.addHeader(Constant.Header_UserAgent, getUserAgent());
                }
            })
            .setClient(okClient)
            .setEndpoint(URL)
            .setErrorHandler(new HttpErrorHandler())
            .setConverter(new GsonConverter(gson))
            .build();
Weibo
  • 1,042
  • 8
  • 18
1

It may be difficult to us to help you without knowing exactly which request your Retrofit Api is building.

So I recommend you to configure a Logging Interceptor to get in touch with what is really happening then if you still don't know what is going on you could come back to us with more information.

Check this answer to discover how to configure LoggingInterceptor with Retrofit 2: Logging with Retrofit 2

Hope that it helps.

Best regards.

Community
  • 1
  • 1
Rodrigo Henriques
  • 1,804
  • 1
  • 15
  • 27
0

I tried all the solutions given here, but unfortunately nothing worked.The only solution i found to call the lifer service from within android is to use lifer mobile sdk.It already has methods and services to call liferay services. You can also call upon your custom services.More info Liferay Mobile SDK

Deb
  • 2,431
  • 3
  • 18
  • 28