Cloud Endpoints custom domain workaround - java

We have an AppEngine app with that we would like to use with Google Endpoints. We need to support a web client as well as mobile clients which is what makes Endpoints attractive to us since we can easily generate Android and iOS client APIs.
The problem is that cloud endpoints currently don't support custom domains, so our web client cannot directly communicate with the endpoints (the mobile clients do not have this issue).
Here is what we've tried already:
CORS requests from the client to the appspot.com domain. The problem with this is since our request do not meet the requirements for simple CORS (custom headers, cookies, etc.), a preflight request must be sent with every request, which slows everything down
Client makes request to our custom domain which in turn makes a request to the appspot endpoint. Again, the extra request is not good for performance
We've also tried setting up a duplicate Jersey REST API just for the web client. We double annotate all our methods (once for Cloud Endpoints and once for Jersey) and the web client accesses the Jersey API and the mobile clients access the Endpoints API. This works pretty well except that Jersey and Endpoints use different exceptions. So if we want to throw a 404 Endpoints exception that will mess up the Jersey response and vice versa.
Are there any other options? We want to use the power of Endpoints for generating mobile clients but also get around the custom domain limitation for the web client.

We ended up ditching Cloud Endpoints entirely and went with a pure Jersey REST API instead.
To deal with our need to generate mobile clients for the API, we annotated our API with Swagger. As an added bonus, Swagger seems to support more client generation than Cloud Endpoints and also makes it relatively easy to setup your own client generation from a template if your target language isn't directly supported.
Jersey + Swagger was not as easy to setup as Cloud Endpoints, but it is more customizable and allowed us to get around the custom domain restriction imposed by Cloud Endpoints.

Google Cloud Endpoints 2.0 now supports custom domains. If you are using Google Cloud Endpoints 1.0 you can migrate by doing the following:
Update your dependency to use the new artifact. In Maven, this looks
something like below:
com.google.endpoints endpoints-framework 2.0.0-beta.8
Remove the legacy dependency, which is the appengine-endpoints artifact.
Update the API entry point in your project web.xml file:
Rename all occurrences of SystemServiceServlet to EndpointsServlet.
Replace all occurences of the path /_ah/spi/* to the new required path /_ah/api/*
See:
https://cloud.google.com/appengine/docs/java/endpoints/migrating
https://code.google.com/p/googleappengine/issues/detail?id=9384

Easiest solution is to use reverse proxy.
For example if your application is http://myapp.appspot.com, create simple html page on http://myapp.com and redirect to http://myapp.appspot.com using javascript.
Index.html on http://myapp.com.
<html>
<head>
<script>
windows.location = http://myapp.appspot.com;
</script>
</head>
<body></body>
</html>
It has one more advantage: if you put your proxy page on another hosting (not appspot.com) your application ( http://myapp.appspot.com ) will be accessible from China.

Related

Should we expose REST API as an OAuth 2 resource server?

I have a spring boot application exposing several REST API endpoints. I want to enable google oauth authentication (authorization code grant) on it. I am guessing what is correct way to do this out of following options:
Have separate application as OAuth 2 client (i.e. with spring-boot-starter-oauth2-client dependency and make the existing app a resource server (i.e. with spring-boot-starter-oauth2-resource-server dependency)
a. This Udemy's course keeps two application separate: resource server, OAuth 2 client. Then it seem to need a proxy REST endpoint in oauth
2 client project corresponding to every REST endpoint in resource server. REST end point in OAuth 2 client retrieves access token and adds it to every request to corresponding REST endpoint in resource server.
b. This stackoverflow threads talks about making same application both OAuth2 client as well as resource server
Make the existing app OAuth 2 client. (that is include spring-boot-starter-oauth2-client dependency) and simply require user to be authenticated to access REST endpoint URLs.
I have following doubts:
Q1. Should REST API always be exposed as resource server? And if yes, then is approach 2 not-so-recommended way? (as it does not expose existing REST API as resource server but as a part of OAuth client with restricted access to those APIs)?
Q2. If approach 2 is not fine, then which of approaches (1.a) and (1.b) are preferred or when to prefer one above other? (I believe (1.a) is more suitable when we want single OAuth client as a point of access for several different resource servers.)
In OAuth2 world, a REST API is a resource-server by definition.
In your scenario, Google currently is an authorization-server. You could hide it behind a Keycloak instance or something else capable of user identity federation if you need to extend to other identity providers (Github, Facebook, etc.) or want some roles definition, but as Google serve JWT access-tokens, you can use it for you resource-server security (if google IDs are enough for your security rules).
In both cases (Google directly or with an OIDC authorization-server in the middle), you can find sample configuration here (or there if you prefer to stick to spring-boot-starter-oauth2-resource-server but it requires more Java conf as you can see in tutorials).
I personnaly don't like to merge client(s), resource-server(s) and authorization-server(s). My clients are generally mobile and web with client-side rendering (Angular), but even for spring clients I'd keep it separate.
There is a special case, thought: when a resource-server delegates some of its processing to another, then, by definition, it is a client too. In that case, it is possible that security requirements and mechanisms are pretty different:
is your API authenticating in its own name (using client credentials flow)? In that case, you might use spring-boot-starter-oauth2-client to negotiate access-token to be used when issuing requests to other service.
is your API issuing requests in the name of authenticated user and does the other service know about the authorization-server which issued user authentication? In that case, you can forward the token you received
is the service you are consuming not OAuth2 at all? (just requires basic auth header for instance)

Securing REST API in JBoss

I'm developing a RESTeasy JSON API under JBoss-As 7.
I have another separate web-server.
I am developing with JAVA on server-side, and on client-side with Javacript, JQuery, AJAX.
So, I have 2 distinct *war*s, let say they can be accessed as following:
https.//localhost:8443/services
http.//localhost:8080/web
Now I want to secure these two guys; RESTeasy API and web-server.
Let me tell about my structure:
I keep the users in DB with username-password. These are the only users for now.
I have a login page to authenticate my users (I don't want http basic auth popup and any workaround about that)
The clients of REST API are browsers (not web server). The static page is load, and then some other dynamic things are load through REST API, calling within from browser using JQuery, AJAX, whatever.
All communication can be through SSL/TLS, no problem.
For the future, scalability (clients other than web-browsers, ability to authenticate with social network logins, etc.) should be in mind.
My scenario is as following:
Client is browser.
Client wants to access a web page web/aaa.html which is restricted to authenticated users.
Client is redirected to login page: web/login.html
Client filled the FORM and sent to ... either,
a) to the rest-api, or
b) to web-server,
not sure (So, here you have an implicit question).
But in any case, what a or b should do is the same:
Check username-password. Let say they are checked and the user is authenticated.
From now on, I should have got these two things at the same time:
1- Client is authorized to navigate the restricted pages.
2- Client will be authorized on REST API calls.
So, I need these 2 things at the same time happen, after authenticating in login page.
I have read lots of things, about authorization in REST API, with tokens, keys, etc. and yes I also have heard about Spring Security, Apache Shiro, etc.
And yes, I do not want to implement a new security framework by own and I will use one. I imagine that some framework can produce/check tokens etc. for me.
Before Spring Security and Apache Shiro, I want to know about resteasy skeleton key JBoss module.
There are these sources:
https://github.com/resteasy/Resteasy/tree/3.0.1.Final/jaxrs/examples/oauth2-as7-example
http://docs.jboss.org/resteasy/docs/3.0-beta-2/userguide/html/oauth2.html
But, they didn't seem to me very explicative, and also I am not sure if they are what I need.
Is there someone who knows how to configure skeleton key (or in general JBoss App layer) and give me useful example to achieve what I've described, please?
Or, could you give me some other advice/example to achieve my goal, especially noting that my question is about "how to implement"? I don't see where to begin.
Thanks in advance.
For securing REST Services, We can use following framework
OAuth (Open source - RFC6749)
Apigee

Is Sitebricks compatible with GAE backends (Java)

I would like to know whether it is possible to host a Google App Engine backend servlet using Sitebricks. I am trying to do so in my GAE Java app -- frontend gets the backend URL using GAE's BackendService interface and send an HTTP Request -- but the HTTP response always returns with a 404 Not Found).
I would love to post some source code / configuration files, but I fell that it may be best for me to explain what I am doing. Basically, my servlet has been configured using Sitebricks in the same exact manner as my frontend servlets that are working perfectly (ie, using the #Service, #At and #Get annotation in the servlet classes and methods, plus configuring SitebricksModule in my app's global Guice Injector instance). I am using a dynamic backend instance, configured properly in backends.xml.
Does anyone have any hints on pairing Sitebricks with GAE Backends?
Yes Sitebricks works on GAE. I recommend the 0.8.8-SNAPSHOT version from sonatype's OSS repo for latest functionality. Otherwise the latest tested release is 0.8.7 from Maven Central. The only bit that doesn't work is requesting other websites from GAE using the Sitebricks Web Client.
Are you using GuiceServletContextListener? This is the best way to create an Injector. Also make sure your web.xml points to it and sets up GuiceFilter correctly (as per sitebricks.org docs).
Dhanji.
(maintainer, sitebricks)

Using the REST API of Twilio

Not being familiar with REST and after reading some doc about it I am a little bit confused about the way it works.
I actually want to use Twilio SMS Gateway that provides a REST API to interact with and send text messages from an existing web-application.
From what I understand, REST is a way to structure a web service and in the end, instead of using SOAP for example, we just access 'resources' with URLs, relying on HTTP to GET, PUT or DELETE data.
The SMS Gateway I am talking about is providing a Java API that I could integrate to my web-app. The classes in this API uses httpcore, httpclient and commons-codec jars. Is this because REST rely on HTTP?
So basically, their API is relying on the Apache and HTTP libs to construct HTTP requests in Java and setting the basics, so I just have to provide with the data I want to submit and/or specific information?
REST API's are HTTP API's. The word REST is supposed to indicate something about how your API works. Basically that you use POST requests to update data and GET requests to retrieve it, and you have different HTTP endpoints for all of the different resources in your API, like Calls or Recordings.
The Twilio helper libraries (including the Java library) are basically wrappers around HTTP calls to the Twilio API. The idea was to make it easier for you to make API calls to Twilio by abstracting away the HTTP authentication and request stuff behind some more language-specific code. We also parse the HTTP response into an object for you.

Implementing an HTTP proxy to overcome cross-site AJAX requests restrictions (?)

I have a Spring-MVC webapp (3.0.5-RELEASE) which needs to access JSON webservices from another webapp on a different sub-domain (from the client/browser via AJAX).
I've solved this in the past by either:
writing a simple controller that proxies the requests, using Apache Commons HttpClient to handle the requests. Thus overcoming the cross-site/cross-origin request security limitations of most browsers
implementing a JSONP service on the server side (when calling our own JSON services) - not always possible
In the case where JSONP is not possible, is there a better way of doing (1.)?
and/or
Is there a library that will handle this for me? So I don't have to write all the HttpClient code myself - its not a lot of code, but I wonder if I'm (badly) re-inventing the wheel.
I have often had to consume third party web services (API), and as you mentioned, JSONP is not always an option. This is how I go about designing:
If the API is user centric, it has to provide a jsonp interface and that's what I will use. User centric means that you cannot perceive any reason to call the API, do some computations with the response, may be call one of your ajax services and then combine the response and show the user.
If my use case includes calling the API, and then acting on the response, like calling additional services from my application, combining the data and then showing it to the user, I would prefer not doing this in the browser. I would instead use RestTemplate and make backend api calls to the service. In which case there are no cross domain restrictions.
The only case where using a Server Proxy to bypass jsonp is when you are creating a Product that allows people to build custom plugins, plugins which are hosted on your page, but need to make Ajax calls to the app developers servers. This is a very involved case! (As as example look at how Apigee creates Public Facing REST API around your existing urls, or how Zendesk allows you to develop apps)
Hope this helps.

Categories