How do I access Google Drive Application Data from a remote server? - google-oauth

For my application I want the user to be able to store files on Google Drive and for my service to have access to these same files created with the application.
I created a Client ID for web application and was able to upload/list/download files from JavaScript (client side) with drive.appfolder scope. This is good, this is half of what I want to do.
Now I want to access the same files from Node.js (server side). I am lost as to how to do this. Do I create a new Client ID for the server? (if so, how will the user authenticate?) Do I pass the AuthToken my user got client-side and try to use that on the server? I don't think this will work as the AuthToke is time-sensitive (and probably not intended to be used from multiple IPs).
Any direction or example server-side code will be helpful. Again, all I want is to access these same files the user created with my application, not any other files in the user's Google Drive.
CLARIFICATION: I think my question boils down to: "Is it possible to access the same Application Data on Google Drive both client-side and server-side?"

Do I create a new Client ID for the server?
Up to you. You don't need to, but you can. See below.
if so, how will the user authenticate?
Up to you. OAuth is about authorisation, not authentication.
Just in case you meant authorisation, the user authorises the Project, which may contain multiple client IDs.
Do I pass the AuthToken my user got client-side and try to use that on the server?
You can do, but not a good idea for the reason you state. The preferred approach is to have a separate server Client ID, and use that to request offline access, which returns (eventually) a Refresh Token, which you store in your server. You then use that Refresh Token to request Access Tokens whenever you need them.
AuthToken is ... (and probably not intended to be used from multiple IPs).
It is not bound to a specific IP address
Is it possible to access the same Application Data on Google Drive both client-side and server-side?"
Yes
Most of what you need is at https://developers.google.com/accounts/docs/OAuth2WebServer

Related

Is there a way for one Apps Script to call another, but in the context of a different user?

I have written thousands of lines of Apps Scripts in an internal enterprise setting, but have been wracking my brain on this without any success for some time. Here's the use case:
App Script #1 is run by users in our organization with Calendar read/write permissions. In order to operate correctly, however, it requires access to certain data that can only be accessed by a separate user with different permissions.
App Script #2 is run as this second user, and serves up an API endpoint via doPost() or doGet() that returns the requested information.
For security reasons it is not possible to grant user #1 the full permissions required for user #2, hence the desire for user #2 to expose an API that provides only a very specific set of information to user #1.
The most intuitive solution would appear to be for user #2 to deploy an Apps Script with the "execute the app as" field set to "me", and the "Who has access to the app" field set to the organization's GSuite domain (for security reasons this must be restricted to within the organization).
However if user #1 then tries to hit that endpoint using UrlFetchApp, the request will fail (I believe with an HTTP 403) since the request does include a session token to prove that the request originates from within the same GSuite organization. Google does not seem to provide a way to generate such a session token; attempting to set an "Authorization" header with the value "Bearer " + ScriptApp.getOAuthToken() does not work.
I have also tried using the Apps Script API to have user #1 execute the script which was deployed by user #2, however the Apps Script API makes it clear that scripts can only be executed in the context of the calling user.
I've also read separately that Google Apps Scripts do not play well with service accounts (https://issuetracker.google.com/issues/36763096).
Hopefully I'm missing something obvious. Any ideas?

Is it good practice or necessary to protect an API with authentication even if the data is not sensitive?

My Vue.js app which interacts with data via a Node.js backend accesses both sensitive and non-sensitive data. I have been able to protect the API's on the Node server, the ones working with sensitive data (such as updating pricing information) using the google authentication API. This requires a user to have to login with a google account before being able to interact with those API's.
I'm now trying to protect the API's which simply retrieve non-sensitive data (such as Names, descriptions, prices of products I sell, etc.) so that even said API's cannot be accessed directly without some form of authentication. ie. If I used something like Postman to retrieve data from the API directly, without authenticating I would not be able to get any data. However, these API's are accessed from a part of the Vue.app which does not require login. ie. Users on the site may see Product, pricing etc. information without having to login first.
In order to protect these "non-sensitive" API's I would have to pass some "secret" such as an API Key from the Vue front-end to the Node backend. I believe from 2 other posts I've done (here and here) that it isn't possible to pass Environmental variables into a Vue App at run-time (I'm using Vue CLI 3). This leaves me with having to hardcode the API Key into the front-end code which means it is no longer "secret" or secure.
I'm in essence trying to do "Application Authentication" but without the ability to pass ENV Variables in Vue at run-time I don't know how to do this securely.
Everything I read on the internet points to either:
Passing ENV Variables into Vue at build-time (which isn't secure in this scenario); or
That I'm missing something for wanting to pass ENV Variables into Vue at run-time in the first place.
Question: Am I overthinking or overcomplicating things by trying to protect data which isn't sensitive?
One way of doing so is the following:
Upon successful authentication generate a JSON Web Token
Send token back to the client (Vue app) and store it in the browser's local storage
On the API route you want to secure add a function that will check whether the the request contains the token you provided on Step 2. You can send the token as part of the request body or maybe a header.
This is a simple yet effective way of securing an API.

passing credential in HttpWebRequest In UrabanCode Deploy

I am using HttpwebRequest to pull list of all Components from Urban-code Deploy to my application. I have used my own credential in the code(C#) to access it. It is working fine. Now, i have to use the Service account that my company has, in order to pass the credential. I tried using DefaultCredential and defaultNetworkcredential but getting same error--Unauthorized access. Any help!!! Thank u!!!
You got an answer on the UrbanCode forum here: https://developer.ibm.com/answers/questions/372586/authentication-using-service-account-without-admin/?smartspace=urbancode
You just need a user account in the system with permissions to access the data. Accessing data via REST API requires the same permissions as through the UI. There's no way to bypass that.

How to get user data from Google API with OAuth remotely from a server?

I've been reading lots of documentation about Google API access and OAuth flow using it but I don't seem to get it working in my mind, so I want to get some help first in order to have a clear idea about how it works then I can code it using the corresponding API.
What I want to achieve is feed a Java application running in a PC with specific Google user data, like localization through Google Latitude API. In order to get this, OAuth must be used, so I need getting the user consent, then access the user data from the application running in my computer, and I don't know how to manage this.
I've already registered my application with the Google APIs Console and enabled the Google Latitude module. I've also tried the Latitude console application here and it works properly (a browser tab opened asking for a Google user; I entered it and I got the location data), but I'm having problems when trying to adapt the program flow to my needs.
In my application, the 'remote' user is supposed to send a request (a custom JSON message) to the server asking for service enable/disable, like allowing the server to track his/her position through Latitude. Then, AFAIK, the server should send to the user a URL so the user can give the consent, but I don't know how to get this URL and how the server realizes about this consent and gets the token (automatically? Google tracks this authorization process?). Once my server gets the specific user token, then I should be ready to get service data for that user using the received token.
As I said before, I've tried according to different references, but as the documentation seems to be really scattered and much of it is already deprecated, I've been unable to get it working.
Judging from your description, the installed app OAuth2 flow seems to be the right one for you.
At some point, presumably when a user is installing your desktop app, you should fire up a browser - either embedded one in your app or the default browser - and sent them to this Google OAuth2 endpoint. In your request, fill out all the parameters as required by the doc: Latitude API scope, client_id, etc. Google, as an authorization server, will take care of user authentication, session selection, and user consent. If the user grants access to her data to your API, you will receive an authorization code either in the title of the browser window or at a localhost port.
Once you have the code, you can exchange it for an access token and a refresh token. The access token is what you need to call the API and access the user's data. It is short lived though - check the expired_in parameter in the response, I believe it is 3600 sec. - so you will need to periodically ping the token endpoint with your long lived refresh token and exchange it for an access token.
You can find a more thoroough description of this flow in the doc linked above.

CAS authentication and limiting access for specified users

I'm using CAS (Central Authentication Service) from Jasig in a client JSF app running on tomcat 6 server. I would like to limit the access to the app just for the users specified in my database rather than all the users which can be authenticated using that CAS service. When the user attempts to log in, I need to check if his username is also in my database's table user and if it is - allow the access to the app. Otherwise, I would like to redirect user to a page "You don't have permission to access this part of the application". So I need authorization as well. Is there a good way to authorize the users in jsf 2.0? Thanks in advance for any help/suggestions.
Sounds like you need to design a custom Authentication Handler class in CAS. In theory, your handler would extend this [1], perform all the necessary checks and database look ups and will then be able to return a signal that indicates whether or not the user could authN.
You should then reference your custom handler in the deploerConfigContext.xml file.
For displaying the message, you could either throw an exception with the proper messages code, such that the message would appear above the login form, or you could alter the spring webflow and generate a new view-state which the user would be redirected to, if they fail to get access. The first approach is much easier to implement.
Another approach would be to take advantage of the isUserInRole() method [2] using the persondir api.
[1] http://developer.jasig.org/projects/cas/cas-server-core/cas-server/cas-server-core/apidocs/org/jasig/cas/authentication/handler/support/AbstractUsernamePasswordAuthenticationHandler.html
[2] https://wiki.jasig.org/pages/viewpage.action?pageId=47874068