apigee gateway, authn and authz: REST API calls another REST API - rest

We are using apigee API gateway and exposing a REST endpoint. We understand apigee supports various options for securing the endpoint.
Our use case is that this REST endpoint should call another REST API provided by a software vendor. Software vendor have their own authentication and authorisation mechanism. Basically they have users and roles concept.
My question what is the best practise in this case? Should we authn and authz at gateway level Or at vendor REST API level or both ?
In any case, there is no escaping authn and authz at vendor REST API level.
Please suggest. Thank you.

In your case it first depends on whether you are simply presenting a proxy in front of the vendor API, or if your own API provides distinctive services and the vendor's API is only one of perhaps several "call outs" your middleware makes to offer its overall value. Another way to look at it is to ask: are the customers of your API endpoint uniquely your customers, or are they really just customers of the vendor's underlying API? You might choose to use your own layer of API client AuthN/AuthZ if this is uniquely your own API 'product' or you may choose to pass-through credentials directly to the vendor API if your endpoint is really just a thin and light abstraction. Net-net, it depends on your end-to-end use-case.

Related

API protection for on-premise product

Context:
We have started exposing the functionality of an on-premise product through REST APIs.
Questions:
How do I protect REST APIs? One of the options is OAuth2 but I don't want a dependency on an OAuth2 server which, IMO, may not be available with all customers. Is HMAC signature a viable option? If yes, what are the advantages and disadvantages as compared with OAuth2?
OAuth 2.0 is the way to go to secure REST APIs. The Authorization Server can be delivered as a part of your product and deployment, it does not need to be a heavy-weight pre-existing component that is run by the customer.

How might I apply multiple security mechanisms to a Swagger-generated REST service?

I have generated JAX-RS stubs for a REST service using Swagger and want to set up the security.
The security side is very new to me and I would like to use standards as far as possible. (In the past, for other J2EE applications, I have used Filters to handle Authentication which put User objects into a Session. As I understand it, Sessions should be avoided for REST.)
There are 4 types of user who will access the services
Customers and business partners (Authentication via oAuth or similar)
Employees (Authentication via NTLM & LDAP)
Developers (Mock authentication/authorisation of some kind)
Integration test (JUnit with pre-defined users and roles)
Is it possible to define a security mechanism which would handle all of these users?
How would I use the Swagger security directives?
Am I making this more complicated than it needs to be?
You could use an open source API gateway like Tyk? Here’s a link to some handy info on API Security in the tyk docs.
And here is a blog post that describes taking a layered approach to API Security that goes beyond the gateway.
Disclosure: I work for Tyk!

Creating an API Layer on top of Firebase Real-Time Database

I do have some data stored in my Real-Time Firebase database. I am willing to expose some of this data via a REST API to my B2B customers.
I know that Firebase is itself a REST API but its authentication mechanisms don't fit my needs. I am willing my customers to access the API with a simple API Key passed in the HTTP request headers.
To summarize, I need an API layer sitting on top of my Firebase real-time database with the following properties:
Basic Authentication via an API key passed in the HTTP request headers
Some custom logic that makes sure customers respect the API limits (maximum requests per day for example)
The only thing I can think of is implementing this layer in AWS lambda but that also sounds a bit off. From the lambda, I would have to access my Firebase database and serve that data. That seems too many network requests; something native to Firebase would be great.
Thanks,
Guven.
Why not have a simple API which provides them an Oauth token for the original firebase REST API if they have the correct Api Key
It'll be more secure as only you'll be able to make the tokens as only you'll have the service account private key. Also saves you the headache of making a whole REST API. Also the Oauth tokens expire relatively quickly so it's less of a risk than a normal key that you furnish
I personally have created my own Servlets where a user posts their data if they are authenticated using an id pass combo.
In the Servlets i use the default REST API provided by Firebase with the Oauth generated in my servlet. This way, i can have the DB security rules set to false for all writes from any client api. And the REST API and their admin sdk on my server ignore the security rules by default.
After some research, I have decided that AWS is the best platform such API related features.
Gateway API lets you setup your API interface in a matter of seconds
DynamoDB stores your API data; you can easily populate the data here
AWS Lambda lets you write the integration code between Gateway API and DynamoDB
On top of these, the platform offers these features out of the box:
Creation & handling and verification of API keys for authentication
Usage plans to make sure that API consumers don't exceed your API usage limits
Most of what I was looking for is offered in these AWS services.

REST API user management URIs

I am writing REST APIs in a MEAN application for user management. Although I normally follow best practices for REST APIs, I do have a security concern about exposing too much detail for user accounts API in the URI.
I would prefer not to include the username or account ID as part of the URI when trying to access a specific user account resource:
/api/accounts/:id or /api/accounts/:username
The one alternate approach I have come across is the use of "me" instead of the resource id:
/api/accounts/me
Most of the use cases I have seen only use GET, but I would like to use this for PUT/POST operations as well:
PUT /api/accounts/me/password
{"oldPassword":"xxx", "newPassword":"yyy"}
Do you think this is a good way? Any other ideas?

maintaining session in REST web service

I have a COTS application(PLM application) which has provided few SOAP APIs to access. Since this SOAP API is highly complex, we are developing a easy to use REST wrapper service. Before invoking any API in my COTS application, authentication API needs to be invoked. In my REST wrapper web service, I have a login resource which invokes COTS SOAP login API. To keep things simple for my API users, I store the logged in user details in user session. In every other REST resoruces, I retrieve the session and check whether session has user details. If yes, I proceed and invoke the SOAP API. if not, I return proper HTTP status code. I use Apache CXF for service and client. I mandate my APIusers to maintain the session in the client like this
WebClient.getConfig(client).getRequestContext().put(Message.MAINTAIN_SESSION,
Boolean.TRUE);
In every REST tutorials, it said REST is stateless. I am doubtful whether what I am doing is correct as per REST standards. Please suggest. Thanks
Basically the idea of REST is a stateless interface. However it is common practice to use some kind of authentication for API calls since most of the time not all resources should be public (e.g. the timeline of a twitter user over the twitter API)
Therefore it is ok if you do some kind of authentication and validate a session on further requests (or maybe authenticate with every single request, e.g. with HTTP Basic Access Authentication) to check if access should be granted.
Not part of this and not the idea of a RESTful API would be to store complex session information that would really make the whole thing stateful. This for example includes storage of information of an older request for processing together with one following later.
client.getRequestContext().put(Message.MAINTAIN_SESSION, Boolean.TRUE)
This code causes cookies to be maintained in that specific client only.
If you want those cookies be available in another client, it needs to be programmed.
And if the second client receives additional cookies and you want those cookies available in the first client too, how is that possible?
I need something like a root client that maintains cookies of all sub clients. All cookies must be shared among all clients. Like a shared cookie repository for all clients. Does anyone know how to achieve this?