How to learn to handle HTTP requests of protected resources? - json

I've wrote a tiny script that retrieves publicly available data from some APIs, in JSON format. I'm now trying to get some protected data out from bit.ly (click stats from a given user) and so I obviously need to authenticate via OAuth.
I don't seem to understand the role of client id and secret, as well as the user API key. I also don't get how to grab an access token (maybe generated during OAuth authentication?) to authenticate my HTTP requests of protected data. Do you guys know any good (e)book, article or any other resources I should read to understand in detail these architectural nuances of authenticated data retrievals and HTTP requests?

It is exactly as you suspect. The access token is granted during the OAuth process, which is basically a three step rocket of getting
Temporary credentials for your application
An end user needs to authenticate those temporary credentials, which grants you a verifier token
And finally you exchange your temporary credentials and the user verification for an access token.
Depending on which language/framework you are using, there are often good libaries available to help you implement an OAuth client. Check out: http://oauth.net/code/
But you will be well served by a clear understanding of how the whole thing works. Twitter has a great tutorial about OAuth 1: https://dev.twitter.com/docs/auth/oauth.
Regarding OAuth 2. Check out http://hueniverse.com/2010/05/introducing-oauth-2-0/. Hueniverse is a good resource for all things OAuth by the way.

Related

To authenticate the client that invokes Google cloud function in Java

I have a google cloud function in Java.
Client will invoke the function using HTTP trigger URL.
But that is not secure. I have gone through some docs saying that you should pass a token or client ID and then verify it in server side.
Can anyone explain that in detail and please provide a code example if any.
My doubt is to authenticate the client while they invoke the function using Http trigger
This page explains quite well all the capacity that you have to authenticate a requester on Cloud Functions.
If you have users, the best way is to use Firebase Auth (our Google Cloud Identity Platform which is simply a more advance solution than Firebase Auth with more features)
However, you need to grant all you user with cloudfunction.invoker role, to allow them to invoke the Cloud Functions. It could be difficult. You can also perform the check on your side, but in this case you remove the security (filter) layer of google and you have to check all the traffic by yourselves (not really safe, in term of billing and in case of attack).
The latest solution, API keys, is not recommended, especially for the users. But for machine to machine it's sometime the only solution. However, there isn't out of the box solution and for this I wrote an article, that explains how to create a Cloud Endpoint (or now a Cloud API Gateway which is the serverless solution of Cloud Endpoint with ESPv2) to accept API Keys.
With this latest solution, if you change your security definition, you can also accept OAuth2 tokens coming from Firebase Auth (or Cloud Identity Platform), but this time, you don't need to grant all the users on your Cloud Functions IAM role. The token only need to be valid and it's the Cloud Endpoint service account which is used to perform the call (and thus which needs to be authorized on the Cloud Functions).
In addition, because you can accept OAuth2 token, you can also accept non Google token, and thus have your users in any IDP OAuth2 compliant (KeyCloak, Okta,...)
You could use external OAuth server like keycloack (https://github.com/keycloak/keycloak), or use somethging like Json Web Tokens -- https://jwt.io/ -- available for various languages, siutable for microservices.

Can secrets be stored in the Code.gs file?

Since we can get a user's email address from the Gmail Add-on API, I'm wondering if we need to authenticate users with OAuth before they interact with our external service or whether we can rely on a stored secret to ensure that requests made with the user's email address are actually coming from a user using the Gmail add-on.
Since app scripts run on Google's servers and aren't modifiable by the user, we could just HMAC the request bodies in the requests to our external API with a secret stored in the Code.gs file. This would (maybe?) ensure that it this endpoint was actually being hit by Google and that the person making the request was the owner of the given email address.
For this approach to work though the secret in the code would actually need to stay secret, otherwise anyone could just hit that endpoint with any email address and post data on behalf of other users. So does this approach actually work, or is there another similar solution that might be feasible?
Otherwise we can just implement OAuth, but if there is a simpler approach that's secure then that would be preferable.
Let's say your external API just need an API key(a secret) to authorize users. You can definitely store it using Properties Service .
But the tricky part is that different user might have different API keys. To solve it , we could ask the user to enter the API key in the UI (can't be masked, though).
This is a very simple approach.
However, I would recommend using OAuth , as it is a more cleaner way.

Service now api how to comment as specific user

I'm working on a project that consumes Service Now API (Rest). To do so our client has registered us as a user in order to login and make all service calls we need to. This project has an interface where users can login once they have an account on Service Now as well, the username they type to log in has nothing to do with service now by the way, but later they associate theirs service now users to it. They can do some operations through this interface, where all of them are done using the integration user/pass not their service now users theirselves, even because they do not need to share their passwords with us. But it's needed to track the correct user to register on service now and I'm in trouble specifically about commenting on an incident. The endpoint to comment is the following :
http://hostname/api/now/table/incident/{sys_id}
where request body is a json object just as simple as :
{
"comments": "My comment is foo bar"
}
but when this comment is registered on Service Now it is under integration user instead the user which commented. Is there any way I could keep a specific user, considering I already have the user id on Service Now ready to inform it on the request the way it should be.
I tried reading Service Now documentation but had no clue how to solve it, altought I've found something about impersonate
This is happening because you're being proxied through the "Integration User" instead of your own account. As long as this is the case, your comments are going to be attributed to the Integration User.
I can think of two ways to fix this issue.
Ask the client to log you into their system directly as a user.
Implement a special API (Scripted REST API, available in Geneva or later) that allows you to identify the Incident and enter the comment, and then the script forges the comment on your behalf, attributing authorship correctly.
The first solution can be expensive due to possible additional licensing costs.
The second solution will require a willing client to devote 2-3 hours of development time, depending on the programmer.
Firstly, you need an integration user with suffient rights. Our integration user has suffient rights out of the box, but your story could be different. A quick check is to try impersonate as other user using menu.
Login as integration user to ServiceNow instance.
Go to https://{instance}.service-now.com/nav_to.do
Click on username at top right corner. This is a drop down.
There should be at least three menu items: "Profile", "Impersonate User", and "Logout". If you do not have "Impersonate User" in this menu, your integration user miss some permissions. Contact system administrator if you miss this menu item to configure appropriate permissions.
Then you need to find sys_id of user that you want to impersonate. For example:
https://{instance}.service-now.com/api/now/table/sys_user?sysparm_query=user_name={username}&sysparm_fields=sys_id
If you have suffient privileges, you could invoke the folling endpoint with sys id of user that you want to impersonate:
HTTP POST to https://{instance}.service-now.com/api/now/ui/impersonate/{user_sys_id} with body "{}" and content type "application/json". You need to provide HTTP basic authentication to this query as your integration user.
The response code on success is 200. The response body could be ignored. The interesting result of this response is a set of cookies for impersonated user in response headers. These cookies could be used for subsequent REST API calls until they expire. Use some HTTP rest client dependent method to capture them and to provide them to next calls.
For Apache HTTP Client (Java), I'm creating http client context using:
HttpClientContext context = HttpClientContext.create();
context.setCookieStore(new BasicCookieStore());
Pass thing context to impersonation request and to subsequent API calls until I get 401 reply, after that I'm reaquiring cookies. Setting new cookie store is important, as otherwise some default cookies store is used.
Two things to note:
This API looks like internal one, so it could change at any time. If it happens, look for what "Impresonate User" menu item does, and repeat it youselves.
ServiceNow permissions are quite fine-grained, so the target user could lack permissions to perform operation. In some cases, if there is no permission to update the field the operation PATCH on object returns reponse 200, but field is not updated. This introduces a surprising mode of failure when you use impersonation.

Node.js security

I am building a basic app using node.js and mysql and just getting a hang of it, I would like to secure the api,like only allow certain people to access the data, maybe by passing a certain token each time a user requests for some information, I tried searching for certain tutorials which used node.js and mysql database and security, I am confused as to which security measure to use, I even read about Json Web Tokens but din't find a proper tutorial for that.Please point me in the right direction.
EDIT
What I meant to say was, only authenticated users are allowed to get access to data in the api, when a random visitor tries to access a URL he shouldnt be alowed to without proper authentication,what I am mostly looking for now is when a user is authenticated the user should be a sent a token of some sort so then gets access to private data,I don't exactly know how to go about this whole thing.Would be glad if you could clear it up for me.
I would look at implementing Oauth2 server in your app. I found this article useful:
http://blog.papersapp.com/oauth-server-in-node-js/
No sure what your exact question is about, but I think the below will help:
Node.js security tips: http://blog.risingstack.com/node-js-security-tips/
Secure Express apps with various HTTP headers: https://github.com/helmetjs/helmet
Go on an educational Web security adventure: https://github.com/toolness/security-adventure
Node.js Security presentation: http://www.slideshare.net/d0cent/nodejs-security?qid=c450507b-e491-4e9a-9b05-89d0c82ea10b&v=default&b=&from_search=6
Take a look at http://passportjs.org/ . Passport has support for alot of authentication methods, however, for your API, you will probably want to use OAuth (http://passportjs.org/docs/oauth2-api). OAuth is what most popular APIs use to authenticate consumers.
For simple projects, You can also use basic authentication, which is what you see when you see the browser prompt asking for username and password. This authentication information can be sent in the header when API consumers makes requests.

How to get an OAuth access token from Google Cloud Messaging on a remote server

I have a general comprehension question about OAuth access token retrieval for a Google Chrome Extension.
I have a popup HTML window in the browser that uses Jquery to request data from the server (a LAMP stack on AWS). The data is presented by PHP scripts which access a MySQL database. All very basic stuff.
I now want to implement a push messaging system using Google Cloud Messaging to alert users of new content that they can check. However I don't really understand where I should request the access token and how to listen for the response. I figure it should be in the PHP scripts but all the Google documentation that I've read states the user has to be present in order to allow access to push messaging. That tells me I should put it in the JavaScript but I feel this is a bad idea because every user could potentially request an access token when I think I only need one every 3000 seconds or so. If my app was completely implemented in PHP I'm sure this would be possible and now I'm worried that splitting it up like this leaves push messaging out of the question. Am I missing a crucial detail or just out of luck?
If the data access you need isn't user-specific, then you're right, there's no good reason to get a separate token for each user. Check out https://developers.google.com/accounts/cookbook/roles/Apps which discusses some options.