I am running Cisco UCCX 11.0 which is a Contact Center server that is based on a Java scripting engine. Scripts are build using the 'Script Editor' software where you drag elements (Java Beans) to define the script logic. One of the steps in the script is to perform a REST Call. Unfortunately this step does not support adding Custom Headers such as Authorization headers and thus is limited to Basic Authentication only.
I would like the script to make a REST Call to an external API that uses a static Bearer Token. Am I correct in saying I could use Kong Gateway for this? Here is my idea of the flow:
UCCX Makes REST Call to Kong with Basic Authentication ---> Kong Gateway recieves the request ---> Kong Gateway makes it's request to External API with static Bearer Token ---> External API responds back to Kong ---> Kong forwards the Response back to UCCX
Is this type of flow possible/easy to deploy?
This can easily be managed by assigning the Request Transformer plugin to the Kong API exposing the upstream service.
Example:
Let's assume you have an API endpoint on Kong called /myapi that is forwarding to your upstream service.
You then assign the Request Transformer plugin to the /myapi API.
For your case, you will most likely want to be using the config.add.headers option when configuring the Request Transformer plugin to add the required header authentication which will be added to all upstream requests.
Relevant Gitter Conversation:
https://gitter.im/Mashape/kong?at=587c3a9c074f7be763d686db
Related
Prerequisites
I have two Cloud Run services a frontend and a backend. The frontend is written in Vue.js/Nuxt.js and is using a Node backend therefore. The backend is written in Kotlin with Spring Boot.
Problem
To have an authenticated internal communication between the frontend and the backend I need to use a token thttps://cloud.google.com/run/docs/authenticating/service-to-service#javahat is fetched from the google metaserver. This is documented here: https://cloud.google.com/run/docs/authenticating/service-to-service#java
I did set it all up and it works.
For my second layer of security I integrated the Auth0 authentication provider both in my frontend and my backend. In my frontend a user can log in. The frontend is calling the backend API. Since only authorized users should be able to call the backend I integrated Spring Security to secure the backend API endpoints.
Now the backend verifies if the token of the caller's request are valid before allowing it to pass on to the API logic.
However this theory does not work. And that simply is because I delegate the API calls through the Node backend proxy. The proxy logic however is already applying a token to the request to the backend; it is the google metaserver token. So let me illustrate that:
Client (Browser) -> API Request with Auth0 Token -> Frontend Backend Proxy -> Overriding Auth0 Token with Google Metaserver Token -> Calling Backend API
Since the backend is receiving the metaserver token instead of the Auth0 Token it can never successfully authorize the API call.
Question
Due the fact that I was not able to find any articles about this problem I wonder if it's simply because I am doing it basically wrong.
What do I need to do to have a valid Cloud Run Service to Service communication (guaranteed by the metaserver token) but at the same time have a secured backend API with Auth0 authorization?
I see two workarounds to make this happen:
Authorize the API call in the Node backend proxy logic
Make the backend service public available thus the metaserver token is unnecessary
I don't like any of the above - especially the latter one. I would really like to have it working with my current setup but I have no idea how. There is no such thing like multiple authorization token, right?
Ok I figured out a third way to have a de-facto internal service to service communication.
To omit the meta-server token authentication but still restrict access from the internet I did the following for my backend cloud run service:
This makes the service available from the internet however the ingress is preventing any outsider from accessing the service. The service is available without IAM but only for internal traffic.
So my frontend is calling the backend API now via the Node backend proxy. Even though the frontend node-backend and the backend service are both somewhat "in the cloud" they do not share the same "internal network". In fact the frontend node-backend requests would be redirected via egress to the internet and call the backend service just like any other internet-user would do.
To make it work "like it is coming from internal" you have to do something similar like VPN but it's called VPC (Virtual Private Cloud). And luckily that is very simple. Just create a VPC Connector in GCP.
BUT be aware to create a so called Serverless VPC Access (Connector). Explained here: https://cloud.google.com/vpc/docs/serverless-vpc-access
After the Serverless VPC Access has been created you can select it in your Cloud Run Service "Connection" settings. For the backend service it can be simply selected. For the frontend service however it is important to select the second option:
At least that is important in my case since I am calling the backend service by it's assigned service URL instead of a private IP.
After all that is done my JWT token from the frontend is successfully delivered to the backend API without being overwritten by a MetaServer token.
I have a legacy SAP Java application hosted on neo platform which uses form based SSO authentication. I want to consume this service from rest client like Postman which is not possible right now. What options do I have?
Is it possible that I write a service on top of the current service and call the "original" service. But again, How do I pass the SSO credentials to the "original" service
We have some Restful services on a certain URI and we wanted to publish our services on the web to use them in our mobile app(written in java),
Our services was on a server which cannot handle too much requests at a same time and used it's proxy_pass functionality for this,
So I used Nginx on an intermediate server to control access to our REST server,
Now we want to protect our services by Oauth2 with Password or Client Credentials(as our mobile users should not login into our servers we cannot display any login page to them),
I setup a Keycloak server which is working and I could get token for my client. I'm going to give my auth/token URI to our mobile developers to get Oauth2 token at first and use it in their requests.
The problem is I don't know how to configure Nginx to authorize incoming REST requests with provided token in request header.
Should I config Keycloak to Handle requests and forward authorized ones to NGINX?
Thanks for your help
After some tries I found this solution:
1- you have to add njs module to nginx this is necessary, you have to compile it first(so in windows it will be much trouble, I tried mingw and stopped at a dependency called expect which is not written for mingw and it wasted a lot of time from me, actually I moved our IAM to ubuntu and compiling njs and nginx in there was done in few minutes!)
2- Introspection is the key subject here, and keycloak supports it, its URI is the same as token URI plus introspect, using Basic Authorization in header and token in body
3- nginx also supports introspection after adding njs module to it, which will let nginx support js code inculde inside config file, a great exaple is NGINX Demoes- Oauth2 Introspection OSS, just copy config file and oauth2.js file and its done. I added api directive at location tag in nginx config file to let callers know it is protected.
4- create one client for nginx in keycloak to do the introspection operation, it should be in confidential mode and Service Accounts should be enabled for it.
5- nginx should forward(proxy pass) auth/token request to IAM, so a location for this should be added in config file.
6- [for ubuntu] I have an error in nginx which tells me it cannot resolve localhost! and installing Bind 9 fixes this for me(another time wasting effort was done here).
7- So any one wants to use our service should request token first and then sends its request attached with token to nginx, nginx introspects token and if token was ok and {"active": true} were received forwards request to resource and passws reply to requester.
All done.
I'm trying to setup AWS Api Gateway as a reverse proxy for my actual deployed API.
My understanding is that I do this by creating a "Proxy" Resource and then specifying my http endpoint URL - as described here
Create and Test an API with HTTP Proxy Integration through a Proxy Resource
This works fine when I try to use the API through the "Test" function within the Resource Editor. I can make calls to any exposed resources using GET methods and see the successful responses.
However, when I deploy the API Gateway API I can no longer access anything using the "Invoke URL" it gives me - I simply get:
{
"Message": "No HTTP resource was found that matches the request URI 'http://<myuniqueid>.execute-api.eu-west-1.amazonaws.com/api/Sector/100'.",
"MessageDetail": "No type was found that matches the controller named 'Sector'."
}
If I remove the "Use HTTP Proxy integration" checkbox from the "Integration Request" I can get it working, but why doesn't it work as a proxy?
I suspect that this is caused by a known issue with the HTTP proxy integration. When you use an HTTP proxy integration, API Gateway passes all headers through to the integration endpoint, including the HOST header. Many existing http endpoint require the use of a HOST header which matches their DNS name and in such cases, passing through the HOST header of the API Gateway can confuse the endpoint.
UPDATE: We identified a work-around for this issue.
In your integration request, explicitly add a header named "Host" and give it the value of the integration endpoint DNS name. This will replace the Host header forwarded from the incoming client request with the Host header you specify. This should allow your backend endpoint to function correctly.
I have deployed a custom UI5 app ( using external REST ful services--> service hosted in another Java stack system) in the front end server.
I used Ajax to call the service directly with the URL as shown below.
This app has run successfully when i use "proxy" in local host(eclipse).
-->Ajax Call code Snippet
So i replaced proxy with target url while deploying in front end. (http ://xxx.xxx:port)
When running from front end server i got cross origin error as shown below.
Error1:<http://xxx:port/xxx/ngservices/rest/query/ZQUE_WEBSERV_APPHISTORY/executeGet. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://xxx:port' is therefore not allowed access. The response had HTTP status code 401>
After enabling CORS plugin in chrome i got unauthorised error as shown below.
Error2:<http://xxx:port/xxx/ngservices/rest/query/ZQUE_WEBSERV_APPHISTORY/executeGet. Response for preflight has invalid HTTP status code 401>
I got the above errors initally while running from localhost.After that i used proxy and it got solved.
I just deployed the app in frontend server and ran it directly. I haven't done any other configurations.
Do i need to do any extra configurations for consuming these external services or kindly suggest any other suggestions.
Important info:
*Able to call external service from localhost(eclipse--> used proxy here) but not able to call service from frontend server.
*Front end architecture: Central hub deployement and connected to SRM,HR and CRM backends currently.
Regards
Phani Poorna
Both of these errors can be solved by creating and configuring a destination on your platform.
A destination is essentially a proxy: when you create it, you specify the backend URL, the authentication mechanism (Principal propagation/basic authentication etc). From your client, you just need to then connect to your destination to query the backend.
What do you mean by Fiori front end server? Are you referring to the Portal service hosted on HANA Cloud Platform?
If so, then you can create a destination by going to Connectivity - Destinations from your HCP account. From your Fiori application, you then need to connect your destination using the following URL pattern:
/destinations/<destination name>/<whatever you want to add to the URL the destination points to>
If you are using a different PaaS, I'm sure it will have some similar way of creating a proxy between your client and your backend. (Edit: I just saw you're using the Central hub deployment - I am not familiar with this system but it must have a very similar way of creating destinations).
Hope this helps, let me know if you have any questions.