3
votes

My overall goal is to be able to automatically download a daily report using the bing ads API. To do this, I need to authenticate with OAuth (the old PasswordAuthentication method doesn't work because I have a new microsoft account). I have been through the "Authorization Code Grant Flow" manually and authorised myself successfully. The problem is:

  • the token is only valid for 1 hour
  • when the token expires, the process requires the user to manually login using a web browser again and re-allow the app access

Here's an example desktop app using OAuth

Does somebody know either

  • a more fitting way of authenticating?
  • or a way of bypassing the user interaction?

SOLUTION:

As mentioned by @eric urban it is only necessary to authorize manually, once. after that, the refresh token will do. (Not really obvious just looking at the example desktop app!)

I wrote a class to deal with all the OAuth stuff and persist the refresh token to a file

public class OAuthRefreshToken {
    private static String refreshTokenFileName = "./bingAdsRefreshToken.txt";
    private static String ClientId = "XXXXX";
    private final OAuthDesktopMobileAuthCodeGrant oAuthDesktopMobileAuthCodeGrant = new OAuthDesktopMobileAuthCodeGrant(ClientId);
    private String refreshToken;

    public OAuthRefreshToken() {
        oAuthDesktopMobileAuthCodeGrant.setNewTokensListener(new NewOAuthTokensReceivedListener() {
            @Override
            public void onNewOAuthTokensReceived(OAuthTokens newTokens) {
                String refreshTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                        .format(new java.util.Date());
                refreshToken = newTokens.getRefreshToken();
                System.out.printf("Token refresh time: %s\n", refreshTime);

                writeRefreshTokenToFile();
            }
        });

        getRefreshTokenFromFile();
        refreshAccessToken();
    }

    public OAuthRefreshToken(String refreshToken) {
        this.refreshToken = refreshToken;
        writeRefreshTokenToFile();
    }

    public OAuthDesktopMobileAuthCodeGrant getoAuthDesktopMobileAuthCodeGrant() {
        return oAuthDesktopMobileAuthCodeGrant;
    }

    private void refreshAccessToken(){
        oAuthDesktopMobileAuthCodeGrant.requestAccessAndRefreshTokens(refreshToken);
    }

    private void getRefreshTokenFromFile(){
        try {
            refreshToken = readFile(refreshTokenFileName, Charset.defaultCharset());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String readFile(String path, Charset encoding)
            throws IOException
    {
        byte[] encoded = Files.readAllBytes(Paths.get(path));
        return new String(encoded, encoding);
    }

    private void writeRefreshTokenToFile(){
        File refreshTokenFile = new File(refreshTokenFileName);
        try {
            FileWriter f2 = new FileWriter(refreshTokenFile);
            f2.write(refreshToken);
            f2.close();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        System.out.printf("New refresh token: %s\n", refreshToken);
        System.out.printf("Stored Safely in: %s\n", refreshTokenFileName);
    }

}

Use it in your app like:

final OAuthRefreshToken oAuthRefreshToken = new OAuthRefreshToken();
final OAuthDesktopMobileAuthCodeGrant oAuthDesktopMobileAuthCodeGrant = oAuthRefreshToken.getoAuthDesktopMobileAuthCodeGrant();
2

2 Answers

1
votes

You are correct that user consent is required up front (once). Thereafter you can use the refresh token to request additional access tokens without user interaction. For details about Authorization Code grant flow using the Bing Ads Java SDK please see Getting Started Using Java with Bing Ads Services. Does this help?

0
votes

The refresh token should not expire that quickly, they are usually permanent or last a very long time. These can however be revoked, or invalidated if you request too many of them. i believe when you have requested more than 25 different refresh tokens, they older ones start to become invalid.