Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android OAuth Retrofit Access Token Request

Can anyone tell the exact format to convert below code into retrofit

curl -X POST -d "grant_type=password&username=admin&password=admin&scope=read+write" -u"clientId:clientSecret" http://myserver/o/token/

I have tried something like this but it isn't working

@FormUrlEncoded
@POST("/o/token/")
AccessTokenResponse getToken(@Field("client_id") String client_id, @Field("client_secret") String client_secret,
    @Field("grant_type") String grant_type, @Field("username") String username,
    @Field("password") String password, @Field("scope") String scope);
like image 883
Revanth Gopi Avatar asked May 09 '15 03:05

Revanth Gopi


2 Answers

Client credentials should be authenticated with Basic Authentication. i.e with header

Authorization: Basic base64encode(clientId:clientSecret)

where base64encode(clientId:clientSecret) is the actual base64 encoded string of clientId:clientSecret. So to update your interface it might look something more like

public interface OAuthTokenService {

    @POST("/api/token")
    @FormUrlEncoded
    @Headers({
        "Accept: application/json"
    })
    AccessTokenResponse getAccessToken(@Field("grant_type") String grantType,
                                       @Field("username") String username,
                                       @Field("password") String password,
                                       @Header("Authorization") String authorization);    
}

Then to set the header, do something like

public class Main {

    public static void main(String[] args) {
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint("http://localhost:8080")
                .setConverter(new JacksonConverter())
                .build();

        OAuthTokenService service = restAdapter.create(OAuthTokenService.class);
        byte[] credentials = "clientId:clientSecret".getBytes();
        String basicAuth = "Basic " + Base64.getEncoder().encodeToString(credentials);

        AccessTokenResponse response = service
                .getAccessToken("password", "admin", "admin", basicAuth);
        System.out.println(response.getAccessToken());
    }
}

Note the above uses Java 8 for the java.util.Base64 class. You may not be using Java 8, in which case you will need to find a different encoder.

I am also using Jackson for conversion, only because I don't use Gson. The above has been tested and should work for you also.

like image 125
Paul Samsotha Avatar answered Nov 14 '22 03:11

Paul Samsotha


With OkHttp interceptors this is made easier.

Interceptor interceptor = chain -> {
        Request original = chain.request();
        Request request = original.newBuilder()
                .header("Authorization", Credentials.basic(CLIENT_ID, CLIENT_SECRET))
                .method(original.method(), original.body())
                .build();
        return chain.proceed(request);
    };

OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(interceptor)
            .build();

return new Retrofit.Builder()
                .baseUrl(baseURL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

The Credentials.basic method will base 64 encode your client id and client secret. The interceptor is then attached to the OkHttpClient client and added to the Retrofit object.

like image 39
Kofi Nyarko Avatar answered Nov 14 '22 03:11

Kofi Nyarko