Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving access token of OAuth 2.0 (implicit grant) from java Desktop Client using SkyDrive REST API.

I am trying to implement OAuth 2.0 implicit grant from java desktop client application using SkyDrive REST API. I use the following code:

Desktop.getDesktop().browse(new URL(st.toString()).toURI());
JOptionPane.showMessageDialog(null, "Press ok to continue once you have authenticated.");

my code opens web browser and ask users to signin and then SkyDrive sends access token to the browser url in the following form:

https://login.live.com/oauth20_desktop.srf?lc=1033#access_token=EwAwAq1DBAAUlbRW.....

What I want to do is to read this access token from my java program. I tried to read httpconnection from console:

HttpURLConnection con = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader( new InputStreamReader(url.openStream()));
while(reader.readLine()!=null){
System.out.println(reader.readLine());

but it seems that java httpurlconnection does not handle javascript response. It replies:

<html dir="..... Windows Live ID requires JavaScript to sign in. This web browser either does not support JavaScript, or scripts are being blocked......<body onload="evt_LoginHostMobile_onload(event);">

So, Is there any way to retrieve the access token directly from java?

like image 887
Zahid Hasan Avatar asked Sep 05 '12 11:09

Zahid Hasan


1 Answers

I had the same problem. After hours of brainstorming, I have finally found a solution. I use the JavaFX library to create a WebView. Then you can intercept location change.

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class Authenticate extends Application {

    static final String APP_ID = "...";
    static final String REDIRECT_URL = "https://login.live.com/oauth20_desktop.srf";
    static final String RESPONSE_TYPE = "token";
    static final String SCOPE = "wl.signin%20wl.offline_access";

    private Scene scene;

    @Override
    public void start(final Stage stage) throws Exception {
        final String url = "https://login.live.com/oauth20_authorize.srf?client_id="+APP_ID
                +"&scope="+SCOPE+"&response_type="+RESPONSE_TYPE+"&oauth_callback=oob&redirect_uri="+REDIRECT_URL;
        BorderPane borderPane = new BorderPane();

        WebView browser = new WebView();
        WebEngine webEngine = browser.getEngine();

        webEngine.load(url);
        borderPane.setCenter(browser);

        webEngine.setOnStatusChanged(new EventHandler<WebEvent<String>>() {
            public void handle(WebEvent<String> event) {
                if (event.getSource() instanceof WebEngine) {
                    WebEngine we = (WebEngine) event.getSource();
                    String location = we.getLocation();
                    if (location.startsWith(REDIRECT_URL) && location.contains("access_token")) {
                        try {
                            URL url = new URL(location);
                            String[] params = url.getRef().split("&");
                            Map<String, String> map = new HashMap<String, String>();
                            for (String param : params) {
                                String name = param.split("=")[0];
                                String value = param.split("=")[1];
                                map.put(name, value);
                            }
                            System.out.println("The access token: "+map.get("access_token"));
                            stage.hide();
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });

        // create scene
        stage.setTitle("Skydrive");
        scene = new Scene(borderPane, 750, 500);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
like image 164
Maxbester Avatar answered Sep 28 '22 18:09

Maxbester