SSL Post Request to Appengine - google-app-engine

I need to develop a web-based service on Google Appengine (Python 2.7) that involves the sending of sensitive data from a third-party website over to my site (preferably through SSL). Say that my url is https://example.appspot.com, and I want the third-party site http://example.com to send two values through a POST request, one is username and the other is password, to https://example.appspot.com/receiverhandler. This receiver handler is class ReceiverHandler(webapp2.RequestHandler). My question is basically: how can I send this POST data through an SSL connection? I'm not entirely familiar with the SSL protocol, so I have no idea where to begin.

Using urlfetch, just send it to the SSL-secured url: https://example.appspot.com/receiverhandler
This gives great explanation of how to do it, using POST params (payload):
https://developers.google.com/appengine/docs/python/urlfetch/

Related

Create Google Cloud Project with Cloud Resource Manager API

I'm trying to create a new project in the Google Cloud Platform using the Cloud Resource Manager API.
It all works fine when I use it through the API explorer however I don't quite understand how to use it as an http request outside of API Explorer.
I run the request like this:
curl -H "Content-Type: application/json" -X POST -d '{"name": "project example","projectId": "my-project-example-1234"}' https://cloudresourcemanager.googleapis.com/v1/projects?fields=response&key={MY_APY_KEY}
Response:
{
"error": {
"code": 401,
"message": "The request does not have valid authentication credentials.",
"status": "UNAUTHENTICATED"
}
}
The documentation says that this request requires an OAuth scope and that's when things get confusing to me.
Reading the documentation I could not understand how one of the required OAuth scopes can be passed with the URL when making the http request to the rest API which I'm only assuming is what I'm missing.
Rather than just tell you how to test with a working token, I'm going to try to more broadly answer what you're aiming to do.
At a pretty high level, you will need to:
Enable the Resource Manager API for your Cloud Console project.
Create an OAuth client ID for Web applications in the Cloud Console. You will need to register your authorized redirect URI. This is where your app will get the OAuth response back from Google when the end user authorizes your app. Note the client ID, you will need that next.
Start the OAuth flow by assembling your URL:
https://accounts.google.com/o/oauth2/v2/auth?
response_type=code&
client_id=<123456789example>.apps.googleusercontent.com&
scope=https://www.googleapis.com/auth/cloudplatformprojects&
redirect_uri=http://<YOUR-APP-URL>/<YOUR-OAUTH-HANDLER>
Replace in that URL the client ID and the redirect URI. I assume you'd have a button or link on your site where you would have the user click to start this flow.
Code your OAuth handler. Some more in-depth code for doing this in Go can be gleaned from this Go Sample, which was originally for G+ sign-in but much of the logic is going to be the same. You are going to get a code query parameter passed to your application, the value is a one-time authorization code that your application must exchange for your OAuth tokens that you use to make API calls on behalf of the user.
If appropriate for your app and situation, securely store your tokens for use later or for processing while your user is not active on your site (might be appropriate for batch processing).
Now that you have an access token, you can pass that to the Resource Manager API and create projects on behalf of the user. You might use the Go client library or you could call the HTTP endpoints directly in your code.
If you want more testing with curl, I'd follow the process that we wrote up accessing the App Engine Admin API. Substitute Admin API URLs and names for Resource Manager and you've got the overall flow. The difference from what's above, is I used a code flow above because I assume you want server-side and possibly refresh tokens if you need to be able to make these API calls while the user is not active on your site.
Like Alex says, you ask for scopes during OAuth authentication. One way to easily authenticate and obtain a Oauth access token is doing:
gcloud beta auth application-default login --scopes=https://www.googleapis.com/auth/cloudplatformprojects
As you can see, you can specify the scopes you want to gcloud and it will take care of authentication for you.
Then, you should be able to create a project calling:
curl -H "Content-Type: application/json" -H "Authorization: Bearer $(gcloud beta auth application-default print-access-token)" -X POST -d '{"name": "project example","projectId": "my-project-example-1234"}' https://cloudresourcemanager.googleapis.com/v1/projects?fields=response
Here, you are passing the access token obtained when you made Oauth authentication. This should be taken care of by the client libraries for you when you get the application default credentials.

Using CORS to restrict who can send a post request

I'm currently trying to configure a route we can call it sub.domain.com/route and on domain.com I have a angular app that sends a post to that end point.
What I'm trying to figure out is do I have to add in CORS to sub.domain.com/route to only allow post requests from domain.com? Or do I have to create a tokening system on domain.comto prevent someone from being able to send curl requests and use that route or to use that route on their website/app without my consent?
I'm trying to limit people who can access that route to only people who are physically on domain.com using my application and clicking the button that sends the post request.
You will need to use some other form of authentication (e.g., tokening, password, etc...) as CORS will only affect whether or not resources such as scripts, served to a user's browser from one domain will be able to interact with services hosted on another. This will do nothing to help against CURL requests, proxies, etc...

get value of access token

I started using google API recently . I am using simpleauth https://github.com/crhym3/simpleauth for authentication to google app engine . Now I am using google blogger API for publishing my blog and fetching data .
This API requires access_token value to use the API https://developers.google.com/blogger/docs/3.0/using#RetrievingPostsForABlog for Authorization . I cant find a way to get value of access token .
Is there a way to get the value of acces token or am I doing something wrong ?
You need to register your webapp with Google to get a client ID and client secret. Then, you can configure your OAuth2 library with these details to allow you to send fully authenticated requests from your webapp to Blogger.
For the specific scenario you listed, retrieving a blog post, I think you can follow step 1 of this page and then follow these steps. You should be able to copy+paste the key from there into the query params of the GET request.
To issue fully authenticated requests, for publishing new posts, for example, you'll have to get your OAuth2 library with the client ID and client secret and have it issue the requests for you.

Cloud Endpoints HTTP Cookies

I am implementing Cloud Endpoints with a Python app that uses custom authentication (GAE Sessions) instead of Google Accounts. I need to authenticate the requests coming from the Javascript client, so I would like to have access to the cookie information.
Reading this other question leads me to believe that it is possible, but perhaps not documented. I'm not familiar with the Java side of App Engine, so I'm not quite sure how to translate that snippet into Python. Here is an example of one of my methods:
class EndpointsAPI(remote.Service):
#endpoints.method(Query_In, Donations_Out, path='get/donations',
http_method='GET', name='get.donations')
def get_donations(self, req):
#Authenticate request via cookie
where Query_In and Donations_Out are both ProtoRPC messages (messages.Message). The parameter req in the function is just an instance of Query_In and I didn't find any properties related to HTTP data, however I could be wrong.
First, I would encourage you to try to use OAuth 2.0 from your client as is done in the Tic Tac Toe sample.
Cookies are sent to the server in the Cookie Header and these values are typically set in the WSGI environment with the keys 'HTTP_...' where ... corresponds to the header name:
http = {key: value for key, value in os.environ.iteritems()
if key.lower().startswith('http')}
For cookies, os.getenv('HTTP_COOKIE') will give you the header value you seek. Unfortunately, this doesn't get passed along through Google's API Infrastructure by default.
UPDATE: This has been enabled for Python applications as of version 1.8.0. To send cookies through, specify the following:
from google.appengine.ext.endpoints import api_config
AUTH_CONFIG = api_config.ApiAuth(allow_cookie_auth=True)
#endpoints.api(name='myapi', version='v1', auth=AUTH_CONFIG, ...)
class MyApi(remote.service):
...
This is a (not necessarily comprehensive list) of headers that make it through:
HTTP_AUTHORIZATION
HTTP_REFERER
HTTP_X_APPENGINE_COUNTRY
HTTP_X_APPENGINE_CITYLATLONG
HTTP_ORIGIN
HTTP_ACCEPT_CHARSET
HTTP_ORIGINALMETHOD
HTTP_X_APPENGINE_REGION
HTTP_X_ORIGIN
HTTP_X_REFERER
HTTP_X_JAVASCRIPT_USER_AGENT
HTTP_METHOD
HTTP_HOST
HTTP_CONTENT_TYPE
HTTP_CONTENT_LENGTH
HTTP_X_APPENGINE_PEER
HTTP_ACCEPT
HTTP_USER_AGENT
HTTP_X_APPENGINE_CITY
HTTP_X_CLIENTDETAILS
HTTP_ACCEPT_LANGUAGE
For the Java people who land here. You need to add the following annotation in order to use cookies in endpoints:
#Api(auth = #ApiAuth(allowCookieAuth = AnnotationBoolean.TRUE))
source
(Without that it will work on the local dev server but not on the real GAE instance.)

URL fetch service - is https secure or not?

I'd like to use the URL fetch service for app engine (java). I'm just sending a POST to one of my own servers from a servlet.
AppEngine -> post-to: https://www.myotherserver.com/scripts/log.php
I'm reading the url fetch doc:
Secure Connections and HTTPS
An app can fetch a URL with the HTTPS method to connect to secure servers. Request and response data are transmitted over the network in encrypted form.
The proxy the URL Fetch service uses cannot authenticate the host it is contacting. Because there is no certificate trust chain, the proxy accepts all certificates, including self-signed certificates. The proxy server cannot detect "man in the middle" attacks between App Engine and the remote host when using HTTPS.
I don't understand - the first paragraph makesit sound like everything that goes from the servlet on app engine, to my php script is going to be secure if I use https. The second paragraph makes it sound like the opposite, that it won't actually be secure. Which is it?
Thanks
There are two things HTTPS does for you. One is to encrypt your data so that as it travels over the internet, through various routers and switches, no one can peek at it. The second thing HTTPS does is authenticate that you are actually talking to a certain server. This is the part App Engine can't do. If you were trying to connect to www.myotherserver.com, it is possible that some bad guy named bob could intercept your connection, and pretend to be www.myotherserver.com. Everything you sent to bob would be encrypted on it's way to bob, but bob himself would be able to get the unencrypted data.
In your case, it sounds like you control both the sending server and the destination server, so you could encrypt your data with a shared secret to protect against this possibility.
The UrlFetch through https has been fixed allowing certificate server validation.
validate_certificate
A value of True instructs the application to send a request to the
server only if the certificate is
valid and signed by a trusted CA, and
also includes a hostname that matches
the certificate. A value of False
instructs the application to perform
no certificate validation. A value of
None defaults to the underlying
implementation of URL Fetch. The
underlying implementation currently
defaults to False, but will default to
True in the near future.

Resources