So my main application is written in Ruby/Rails and that is where the preliminary oauth2 action is happening. Currently I store the email and refresh token from that initial interaction, and now want to use a Scala script to retrieve data from the api in the background using the users credentials. (the point of an API no..?)
After following many examples from the google java api client example page:https://github.com/google/google-api-java-client-samples, I have found that they want me to re-authenticate users via opening a new tab and physically log in. Because I've already authenticated them, is there a way for me to simply continually retrieve data without requiring them to log in again, as this script should be running in the background?
To refresh an access token using the java-api-client library:
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
val credential = new GoogleCredential.Builder()
.setTransport(transport)
.setJsonFactory(jsonFactory)
.setClientSecrets(CLIENT_ID, CLIENT_SECRET)
.build()
credential.setRefreshToken(refreshToken) // get token from DB or wherever you have persisted it
credential.refreshToken()
credential.getAccessToken // returns new, refreshed access token
Related
I am working on creating a simple desktop program in Java, and I want to upload files via this program to Dropbox, but the problem is that the access token has a short life (temporary), how can I make the access token have a long life, or if I can use the App key and App secret?
I need a simple solution like a method or a java example.
Is there anything better than Dropbox in this aspect and more flexible?
Thanks for any help.
This method works fine but the access token expires after a few hours
private void testUplaod() throws FileNotFoundException, IOException, DbxException {
DbxClientV2 client;
DbxRequestConfig config = new DbxRequestConfig("dropbox/TestUplaod");
try (InputStream in = new FileInputStream("D:\\t1.txt")) {
client = new DbxClientV2(config, ACCESS_TOKEN);
FileMetadata metadata = client.files().uploadBuilder("/t1.txt")
.uploadAndFinish(in);
}
I was expecting it would work sustainably.
When you get the access token, you should also receive a refresh token. When the access token expires, you make an API call with the refresh token to get a new one.
Dropbox is no longer offering the option for creating new long-lived access tokens. Dropbox is switching to only issuing short-lived access tokens (and optional refresh tokens) instead of long-lived access tokens. You can find more information on this migration here.
Apps can still get long-term access by requesting "offline" access though, in which case the app receives a "refresh token" that can be used to retrieve new short-lived access tokens as needed, without further manual user intervention. It's not possible to get a refresh token from the "Generate" button; you need to use the OAuth flow. You can find more information in the OAuth Guide and authorization documentation. There's a basic outline of processing this flow in this blog post which may serve as a useful example.
The official Dropbox Java SDK can actually handle the process for you automatically, as long as you supply the necessary credentials, e.g., as shown retrieved in the examples.
I've recently faced a problem.
My frontend use Oauth2 to authenticate my user on Azure (Organization). This giives me multiple information containing idToken and accessToken.
My Backend uses AADResourceServerWebSecurityConfigurerAdapter to authenticate the user thanks to the idToken put in the Authorization Bearer header from the frontend.
Unitil here everything works well. I can get the connected user with this:
public static String getConnectedUserEmail() {
return (String) ((AADOAuth2AuthenticatedPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getAttributes().get("preferred_username");
}
I use my backend app credentials to contact the graph api on behalf of the API itself.
Though, following Azure Ad documentation, I cannot query group/calendar on behalf of the API, I have to do it on behalf of the user.
To respect SOLID principles, I want to make the request from the backend, but on behalf of the user.
I cannot find any information about that.
So here is my final question: How can I make a graph API request in my backend on the behalf of the user?
Knowing that trying to use the tokenValue (idToken) of the user or the accessToken value returns invalid credentials from Microsoft.
You requested GET /groups/{id}/calendar to get group calendar as you said.
You can call Graph API with the access token using on-behalf-of flow, see here.
There is a sample using the On-Behalf-Of flow: https://github.com/Azure-Samples/ms-identity-java-webapi
Note: Make sure the following delegated permission is added.
I was trying to use the service account of my app to access to all documents of all users in my domain following this instruction:
https://developers.google.com/drive/delegation
But it didn't work.
Could you please help me out on this??
I tried to follow URL -
http://iambusychangingtheworld.blogspot.co.uk/2013/12/google-drive-api-how-work-with-domain.html
and code -
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(TRANSPORT)
.setJsonFactory(jsonFactory)
.setServiceAccountId("SERVICE_ACCOUNT_EMAIL")
.setServiceAccountPrivateKeyFromP12File(
new java.io.File("SERVICE_ACCOUNT_PKCS12_FILE_PATH"))
.setServiceAccountScopes(scopes)
.setServiceAccountUser("abc#xyz.com").build();
its working fine But should give me details for all the user for this domain... instead it gives me only for one useraccount.. In the Service account doc it says it should be able to access all the users data under this domain.. am I missing something>?
FYI... Scopes are added , APIS are enabled for this account
Is there any way I can get it??
I have also seen below links but was not of -
Not able to access my google drive Files with service account
The service account with domain-wide delegation allows you to access each account's data one at a time.
If you want to access all the users' data in a domain, you will need to generate a different token for each user (passing the email in the setServiceAccountUser() method) and make the API call for each user.
I've been trying to write a web application using Google Plus API and i need to set up OAuth access with java , I searched a lot and found google java starter and other examples and they were very confusing, I can't figure out what the code that I should write to get the token
I hope if there is someone who can tell me how to get the OAuth access with java in straight forward steps, I saw other questions on stackoverflow.com but they weren't very helpful for me
so any help would be very appreciated :)
The latest Google+ Java Quickstart is pretty straightforward, perhaps you found an older project when searching? Also, the documentation for getting started on Google+ with Java should help to get you going.
The following snippet shows you the relevant code for exchanging the authorization code for an access token when using the hybrid client/server flow:
GoogleTokenResponse tokenResponse =
new GoogleAuthorizationCodeTokenRequest(TRANSPORT, JSON_FACTORY,
CLIENT_ID, CLIENT_SECRET, code, "postmessage").execute();
// Create a credential representation of the token data.
GoogleCredential credential = new GoogleCredential.Builder()
.setJsonFactory(JSON_FACTORY)
.setTransport(TRANSPORT)
.setClientSecrets(CLIENT_ID, CLIENT_SECRET).build()
.setFromTokenResponse(tokenResponse);
I'm removing the lines performing the requisite checks discussed in this thread for simplicity.
// Store the token in the session for later use.
request.session().attribute("token", tokenResponse.toString());
It's worth noting here that you want to persist these credentials unless the user disconnects your app. The sample is using a session because in production environments, the session can be DB-backed and will be restored after the server restarts.
After you have the access / refresh token and expiration time, build the credentials for the OAuth v2 token and then the library will internally refresh the access token appropriately. The following code shows how this is done on the quickstart by retrieving the token data from the user's session and also includes an API call performed by the client, proving the server's Java client is working:
// Build credential from stored token data.
GoogleCredential credential = new GoogleCredential.Builder()
.setJsonFactory(JSON_FACTORY)
.setTransport(TRANSPORT)
.setClientSecrets(CLIENT_ID, CLIENT_SECRET).build()
.setFromTokenResponse(JSON_FACTORY.fromString(
tokenData, GoogleTokenResponse.class));
// Create a new authorized API client.
Plus service = new Plus.Builder(TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
// Get a list of people that this user has shared with this app.
PeopleFeed people = service.people().list("me", "visible").execute();
If you wanted to do this differently, you could explicitly construct the tokenData object from the access token, refresh token, and so on, before constructing the Plus service object.
How can I authenticate programmatically to Google?
Now that ClientLogin (https://developers.google.com/accounts/docs/AuthForInstalledApps)
is deprecated, how can we perform a programmatic authentication to Google with OAuth2?
With ClientLogin we could perform a post to
https://www.google.com/accounts/ClientLogin
with email and password parameters and obtain the authentication token.
With OAuth2 i can't find a solution!
#
My app is a java background process.
I saw, following this link: developers.google.com/accounts/docs/OAuth2InstalledApp#refresh, how to obtain a new access token using a refreshed token.
The problem is that I can't find a java example about how to instantiate an Analytics object (for example) to perform a query when I have a new valid access token
This is my code that returns a 401 Invalid credentials when invoke the "execute()":
public class Test {
static final String client_id = "MY_CLIENT_ID";
static final String client_secret = "MY_SECRET";
static final String appName = "MY_APP";
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
static String access_token = "xxxx";
static String refreshToken = "yyyyy";
public static void main (String args[]){
try {
GoogleCredential credential =
new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setClientSecrets(client_id, client_secret).build();
credential.setAccessToken(access_token);
credential.setRefreshToken(refreshToken);
//GoogleCredential
Analytics analytics = Analytics.builder(HTTP_TRANSPORT, JSON_FACTORY)
.setApplicationName(appName)
.setHttpRequestInitializer(credential)
.build();
Accounts accounts = analytics.management().accounts().list().execute();
} catch (Exception e) {
e.printStackTrace();
}
}
What is the problem?
Check the OAuth 2 flow for Installed Application:
https://developers.google.com/accounts/docs/OAuth2InstalledApp
It still requires the user to authenticate with a browser the first time, but then you can store the refresh token and use it for subsequent requests.
For alternative solutions, check the Device flow or Service Accounts, they are explained in the same documentation set.
I found the Google Java client to be overly complex and poorly documented. Here's plain and simple Servlet example with Google Oauth2. For a background process you'll need to request access_type=offline. As others have mentioned you need the user to do a one time authorization. After that you can request refresh tokens as google tokens expire in an hour.
Although I appreciate that the OP was originally targeting the OAuth2InstalledApp approach, I would like to point out a working solution using the OAuth2WebServer approach. They don't differ significantly and this worked for me. I have found the google OAuth library to be pretty good as it will handle most of the OAuth dance for you and it makes it easy to refresh the access token. The solution below depends on using a pre-obtained refresh token.
As the accepted answer states, to get OAuth authentication working (even for a Java background process) where the request relies upon access to user data
requires the user to authenticate with a browser the first time, but then you can store the refresh token and use it for subsequent requests.
From previous comments by the OP I see the following
So I followed OAuth2 for Web Server Applications (here offline access is documented) but I have still problems.
1) I perform the first request via browser and I obtain autenticaton code for offline access
2) I perform a java post of the authentication code and obtain acces token and refresh token
The approach I used is more like
1) I perform the first request via a browser and obtain the refresh token for offline access
2) In java I provide the refresh token to the library and the library will obtain the access token etc
specifically, using the google-api-java-client library the code is quite straightforward and note that I haven't set an access token as the OP did, as I am calling credential.refreshToken(); elsewhere. (I check if I have a valid access token already and if not call refresh prior to the API call)
private Credential generateCredentialWithUserApprovedToken() throws IOException,
GeneralSecurityException {
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
InputStreamReader inputStreamReader =
new InputStreamReader(jsonFileResourceForClient.getInputStream());
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(jsonFactory, inputStreamReader);
return new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
.setClientSecrets(clientSecrets).build().setRefreshToken(REFRESH_TOKEN);
}
Note this covers step 2 of my approach, and the REFRESH_TOKEN mentioned in step 1 can be obtained as explained below.
First there is a prior set up of a web app creating an OAuth 2.0 client ID on the Google console for Credentials where you end up with a downloaded json file which will be read into the GoogleClientSecrets object.
i.e.
Make sure you add the Google playground callback uri into Authorized redirect URIs
Then you have your client id and the client secret ready for the playground and you can also download the json which you can pull into your Java code.
The REFRESH_TOKEN is obtained by sending a request to the google oauth playground with the following configuration. Note that prior to Step 1 and selecting your scope you should go to settings to check that you are providing you own credentials and add your client id and secret just below that
Note that the Access type is Offline, which corresponds to this.
There is also a nice explanation on grabbing the refresh token here https://www.youtube.com/watch?v=hfWe1gPCnzc
That is enough to get going and is a one time set up!
Regarding refresh tokens you should be aware of their lifecycle as discussed in the docs here
In the oauthplayground you will see this
but on point 4 of the docs here it says this
Hmmm.
Also for reference see How do I authorise an app (web or installed) without user intervention? (canonical ?)
For applications that authenticate on behalf of themselves (i.e., to another application, traditionally by signing into a role account using a shared password), the OAuth2 alternative to ClientLogin offered by Google is Service Accounts:
https://developers.google.com/accounts/docs/OAuth2ServiceAccount