Use case for #EnableZuulServer - netflix-zuul

I am wondering what use case would be served by #EnableZuulServer?
In my case I want to use the ZuulFilter framework for micro-services, and also the spring handlerMappings on Controllers to be called after passing through the Zuul Filter framework. Do not want proxy forwarding.
Is that possible and how? Can we use #EnableZuulServer mode for this scenario? I didn't find much documentation to be able to understand how #EnableZuulServer would work.
Can someone explain and help?

From the Spring Cloud Netflix documentation:
Spring Cloud Netflix installs a number of filters based on which
annotation was used to enable Zuul. #EnableZuulProxy is a superset of
#EnableZuulServer. In other words, #EnableZuulProxy contains all
filters installed by #EnableZuulServer. The additional filters in the
"proxy" enable routing functionality. If you want a "blank" Zuul, you
should use #EnableZuulServer.
Based on that, the answer to your question is: yes.
You can add the #EnableZuulServer annotation and you will not get proxy forwarding but you will still be able to use the ZuulFilter framework.
That said, if you're just looking to filter requests and responses, you can use a standard Servlet Filter along with a FilterRegistrationBean(relevant javadoc)
As far as a use case goes, you'd use #EnableZuulServer when you need more customized behavior than what is available with #EnableZuulProxy.
So, for instance, maybe for debug purposes you want to be able to support a request header that proxies your request to a specified host when the request originates from within a specific IP range.

From the Spring Cloud Netflix documentation:
In this case the routes into the Zuul server are still specified by
configuring "zuul.routes.*", but there is no service discovery and no
proxying, so the "serviceId" and "url" settings are ignored.

Related

How to bring two Cloud Run Apps under one domain to avoid CORS

I have two apps I wanted to have "fully managed" by Cloud Run. One is a pure Vue.js SPA and the other is the belonging backend server for it that is connected to a MySQL and also fetches some other API endpoints.
Now I have deployed both apps but am totally unaware on how I can give the frontend app access to the backend app. They should be both running on the same domain to avoid the frontend from.
Current URL of the frontend app: https://myapp-xl23p3zuiq-ew.a.run.app
So I'd love to have the server accessible by: https://myapp-xl23p3zuiq-ew.a.run.app/api
Is this somewhat possible to achieve with Cloud Run?
I was having the same issue. The general idea that one usually has is to use path mapping and map / to your client and /server to your backend. After googling for a while I found this:
https://cloud.google.com/run/docs/mapping-custom-domains
Base path mapping: not supported
The term base path refers to the URL
path name that is after the domain name. For example, users is the
base path of example.com/users. Cloud Run only allows you to map a
domain to /, not to a specific base path. So any path routing has to
be handled by using a router inside the service's container or by
using Firebase Hosting.
Option1:
I ended up creating an "all in one" docker image with an nginx as reverse proxy and the client (some static files) and server (in my case a python application powered by uwsgi).
If you are looking for inspiration, you can check out the public repository here: https://gitlab.com/psono/psono-combo
Opttion2:
An alternative would be to host your client on client.example.com, your server on server.example.com and then create a third docker run instance with a reverse proxy under example.com.
All requestes would be "proxied" to the client and server. Your users will only interact with example.com so CORS won't be an issue.
Option3:
Configure CORS, so people accessing example.com can also connect to server.example.com
Currently this is not possible in Cloud Run, as already said on the comments to your question.
You could check if there are any Feature Request for this functionality on Buganizer (Google Issue Tracker), currently there seems to be none, and if that is indeed the case, you can create a new Feature Request by changing the request type from Bug to Feature Request and as Google develops it on their road map, you will be informed.
Hope this helped you.

How to set traefik with OAuth2 authentication

I'm using traefik as a reverse proxy. I want to set OAuth2 authentication for a entry point.
In the document, I found the Forward Authentication which I think may be useful for this. But the document is just too simple
This configuration will first forward the request to http://authserver.com/auth.
If the response code is 2XX, access is granted and the original request is performed. Otherwise, the response from the authentication server is returned.
I've no idea how can I achieve authentication OAuth2 within a forwarding?
I've tried oauth2_proxy but didn't find a solution.
In this issue/comment guybrush provided a solution. But that, in fact, was a double reverse proxys.
I've recently built an app for this: https://github.com/thomseddon/traefik-forward-auth
It uses Forward Authentication, as you mentioned, and uses Google OAuth to authenticate users.
There's an example Docker Compose setup here: https://github.com/thomseddon/traefik-forward-auth/blob/master/examples/docker-compose.yml. See the traefik.toml file to see how Traefik is configured to point at the app.
Let me know if it is helpful!
Instead of trying to make Traefik support your case, let Traefik do what it does best and instead use Keycloak Gatekeeper for authentication (and potentially authorization).
This would change your setup from
Client -- Traefik -- Service
to
Client -- Traefik -- Gatekeeper -- Service
This means that both Traefik and Gatekeeper act as reverse proxy.
It's incredibly simple to model complex auth setups with this approach. One potential drawback is however the additional RP layer, so for high performance setups this may not be an ideal solution.
Note that Gatekeeper can work with any OIDC compatible IdP, so you don't have to run Keycloak to use it.

UI5 oData Service for two (or more) different backends

At the moment i still only have about 2 months of experience in UI5. i developed a little sample-app, used sap gateway builder to pass my requests to sap backend.
Now my employer asked me to research the possibility to access two different backends (one sap, one nonsap) via odata from the same app. After a little reading and thinking i came to the conclusion that it would be best to access both backends from a single gateway.
Since ive already worked with sap gateway, i wonder if there is a way to access nonsap backends with sap gateway? Are the better options?
Or is my current approach complete wrong and i should think about a whole other way?
It depends on your approach and the non-sap-system:
Is the non-sap-system accesible via Webservices? Then use second data model (e.g. JSON/ODATA) within SAPUI5 by loading data via webservices after initial loadup of your application.
Is the non-sap-system connected to SAP? E.g. via RFC or another technology, then you can read data from the other system during calling your initial Gateway service and simply call your RFC function module in your method.
From my opinion you will not achieve an 'easy' way to read both via one single SAP NetWeaver Gateway.
Not sure why you would want to access a non-SAP oData service via SAP Gateway. On the other hand you may want a router of some sort so that all services are exposed on the same network location and then incoming requests are routed to the appropriate backend for action.
You may also want to "mash-up" the SAP and non-SAP services into some sort of new service. In that case maybe look to some of the API management tools like Apigee to help you achieve that.

oAuth 2 implementation before moving google container

We are running two restful apis, one with http and the other is with udp.
They are running on premise infrastructure and within next few release, we'd need run them as google container once we dockenize them
Before we put the service up in cloud and all that, we need to implement oauth!
My question is that where to start and how we should approach implementing oauth 2 considering the road map I described?
Truly appreciate any suggestions.
It kind of depends on what you want to use OAuth2 for.
One option is toThere are OAuth2 implementations for most languages (e.g. https://cwiki.apache.org/confluence/display/OLTU/Index)
This allows you to keep your own login/password system.
If you'd rather delegate the auth and identity to a provider like Google, then you just need to implement the OAuth2 dance to get a user's identity from Google, see https://developers.google.com/accounts/docs/OpenIDConnect for more details.
(and when it comes time to use container engine, visit us on IRC #google-containers if you have questions about containers and Google!)

iOS app with Django

So we currently have a website that was created using Django. Now, we would like to create a native iOS app that uses the same backend, so we don't have to re-code the whole thing. From my understanding, there are two alternative routes:
1) Call directly Django URLs, which then calls a function. Within that function, create a HTTPResponse, with encoded JSON data and send that back.
2) Create a REST Service from the Django server with something like Tastypie. However, aside from doing straight-forward GET calls to an object, I don't see how we can call custom functions in our Django Models from TastyPie. Can we even do that?
I find it surprising that there is not a lot of information about consuming a web service from iOS with existing backends like Django or RoR. For example, I know that instagram uses Django, but how do they communicate from iOS to their servers?!
Thanks a lot!
I am currently working on an iOS app for iPhone, with Django / Tastypie in the backend. We do both 1 and 2. The resources are offered REST-style (after auth) via Tastypie, and any custom function calls (for example, creating a new user) are handled by views.py at various REST endpoints, which returns JSON.
When you can you should try to use a common way of doing something instead of reinventing the wheel. Given that, REST is a standard style of software architecture for distributed systems and it works very well when you work with entities/objects.
If you have an API where you interact with entities, it is recommended to use REST interfaces. On python you have Tastypie or the newer Django Rest Framework that does almost all the work. As you propose in 2)
If you have an API where you interact with services, like a login, then you should build an RPC service, basically a function with remote access as you explain on 1).
Normally you will need both ways on a robust application. And YES, it is possible to do that. I agree with #sampson-chen, we are doing the same. We have a REST interface with tastypie, and other methods are done with custom RPC services.
The performance in our case is still good, but mostly depends on the methods you call inside your services, for example, a DB query. You have a lot of ways to improve speed, for example using Celery to queue heavy jobs.
Hope it helps.
REST APIs, while very useful, limit you to GET, POST, PUT, DELETE actions, which are performed upon resources. This can make it difficult to express other action types, such as sending an email. There are a few ways I've found to handle this within django/tastypie:
Issue a PUT/PATCH request on an existing resource, setting a flag that lets your backend know to trigger an action. Detecting if a flag was set can be done inside post_save signal handlers (use django-model-utils FieldTracker to see if a field was changed from False to True); this also helps make sure your application logic works the same outside your REST API (such as changes via the admin site, a celery task, an HTML based view, or the Python shell).
Create a non-ORM Resource (e.g. /api/v1/email/) and override the post_list() method, calling your function there.
As mentioned elsewhere, create a subordinate resource (/api/v1/myresource/send/).

Resources