Microservice Architecture design for subscription - rest

Would like to get some opinion on designing a system with subscription model using microservice architecture.
We implemented an identity server which authenticates and authorizes
users, and stores their subscription profile. (i.e. resources they can
access like which magazine and issues)
on the resources service, the subscription profile will be used to
filter their eligibility. example, if their subscription starts from
Year 2018, then this will take effect and return only year 2018 data
to the users via REST API.
Is this a standard/proper microservice architecture implementation? or any better ways to design this?

I'd argue no, especially if you want to embrace the principles of microservices - you're storing authorization and application domain specific data in your Identity server. Your IDP should only be concerned with authentication concerns.
I'd suggest a separate service or set of services for managing and retrieving this additional information that is linked to user entities in your IDP via a correlating ID (e.g. subject ID, email address, account code etc). This service would own its own data and be consumed by anything which needs to know about subscriptions and the like.

Related

JWT Authorisation through multiple microservices

The question in short
What would be the correct way to handle JWT authentication for a user
who is accessing data from microservice A but where microservice A requires data from Microservice B.
The Setup
I am using Auth0 to issue and handle authentication and authorisation.
I have two microservices set up. The user is logged in on the front end and needs to load tenant-based accounting information.
Microservice A is an aggregate service that communicates to multiple different services in order to provide a standardized response for different types of data types.
Microservice B is queried by Microservice A in order to retrieve vehicle information owned by the user.
Which solution would be the correct approach?
Solution A:
The token that was issued to the user when he logged in will be used by MS A to communicate with MS B. MS A is essentially forwarding the token provided by the user.
Solution B:
MS A has its own JWT which has super admin rights to access any resource from MS B. MS A will use this token when accessing resources from MS B and MS A will take responsibility for ensuring that resources not accessible to the user are not returned in the aggregated dataset.
In solution B you put a lot of responsibility on MS A to properly handle the data. In my opinion it's just asking for trouble, eventually someone will manage to call MS A in such a way to get some more data than they can access. So I would go with solution A, or a variant of it. There are a couple ways how tokens can be shared between services - passing the same token, embedding tokens or exchanging tokens. I have written an article about Token Sharing a while back, you can have a look at it.
I think it depends - both options are OK depending on the scenario.
Here are a few things to consider.
Does microservice B do any resource owner authorization e.g. using the sub claim from the users JWT? If so it might be easier to just pass through the user access token. Note: generally I only use data inferred from the JWT for authZ logic. If you need something like the resource owner ID as part of the business logic, you should explicitly include this in the request payload, so that the service can also be consumed by back-end services using M2M tokens.
With Auth0, there's a cost for machine MUAs (monthly unique authentications). This is separate to the cost for user MUAs. For an enterprise account the default is 1000 M2M MUAs. Increasing this number is pretty cheap, but still something to consider. In general you should configure your M2M tokens to have a longer expiration (e.g. 1-2 days) and use token caching. Generally an in-memory cache will suffice, but if you're building serverless apps (e.g. AWS Lambda, Azure Function Apps, etc) you'll probably need a distributed cache. All this is extra work, complexity, and potentially cost (e.g. for distributed cache) for M2M tokens.
There's additional network request (to Auth0) for M2M authentications. This is mitigated through the use of token caching, but something to consider as well.
Is microservice B going to be publicly accessible? If yes, you may have some security considerations as users will be able to call microservice B directly with their access tokens (obtained legitimately), but they might be able to tamper with requests in ways you weren't intending.
The company that I work for use a mix of the 2 approaches you mentioned (which generally depend on the scenario). We have some helper utils for things like token caching etc., which make both approaches easy enough, but if you're going to use M2M tokens you'll probably have a bit of additional work up-front.
One last thing to mention; when implementing 'transitive' services like microservice B, I think it's good to ensure the service is consumable by both user and machine tokens. You're authZ policies might allow for one or the other (or both), but at least you'll have the flexibility to change if/when needed.

Making API requests to a 3rd party that requires authentication

Here is my scenario. Imagine there is a Yoga studio that uses a professional booking and reservation system that exposes an API. Through this API an application can make a reservation for a client. The API takes the client's userid and password to make the reservation. The booking API doesn't use OAuth or any social media sign-ins.
My desire is to create an Assistant Action that would retrieve the list of classes and allow the client to make a booking.
My puzzle is what design/architecture to look towards to supply the userid/password pair required by the booking API.
How have others solved this puzzle?
Should I store the userid/password as "user state" associated with the action?
First, you should have a conversation with the API provider about why they don't provide an OAuth-based solution. This is a security vulnerability waiting to happen, if it hasn't already.
Second, you need to think very carefully about your own risk profile in this case:
Google does not allow you to collect credential information (ie - passwords) through your Action.
Because of this, you must use Account Linking to authenticate them.
This means that you will need something (ie - a database or data store) to manage their account on your side.
This database would be a good place to keep the username/password you need to use for them for the API...
...but it now means that you need to take extreme care about protecting this database.
You don't really say how this API allows for accounts to be created and managed. If these accounts are just used for you (ie - the user doesn't necessarily see them), then you can mitigate some of that risk by treating the username/password as an opaque token that you manage and generate and that the user never sees.
If this is something that the user is aware of, then you'll need to approach the account linking in one of two ways:
Have them log into your service via an app or webapp using this credential info that you will need to save (ack!) and then link to the Assistant using OAuth.
Have them log into your service via an app or webapp using Google Sign-In, which will carry over to your Action. Then have them provide the credential info for the API, which you will need to save (ack!).

How should I secure this public API?

I have built a REST API that will be integrated into existing consumer booking systems/applications and enable their clients (end users) to book additional goods/services that my company provides.
For example, end user books accommodation and, if the booking system they used has fully integrated our API, that user can also rent a car for his trip.
So the three parties involved in this B2B2C business (in a mini-flow chart) are:
API (My company) <--> Client (Booking Provider) <--> (Client's Client) End user
On behalf of the end user, our client (the booking provider) can call the following of our endpoints:
Check product availability
Place order
Cancel order
We want booking providers to 'install' our API services in their system, thus providing our services to their end users, and then not really have to worry about it (i.e. not have to login all the time to reauthenticate). My question is, how would you protect these endpoints?
Api Key - so the booking provider hardcodes the key in their requests?
JWT - the booking provider has to hardcode their login details to automatically retrieve an access token everytime there is a session?
Oauth - same issue as JWT?
None of these seem optimal. If you have any advice I would be very grateful.
In my opinion there is not much difference between Api Key and JWT/OAuth in the scenario you described.
Personally I would choose an Api Key, or if you really need to maintain a higher level of security you could think about a certificate based mutual authentication.

Pub/Sub Authentication concept for decentral publisher

Context: We are hosting an online shop that needs to track customer behaviour. To achieve this tracking we have integrated several tracking events based on the customer journey in our shop. Based on the GDPR requirements in Europe we are forced to send the tracking events to infrastructure that is controlled by us as a company. Sending data via the Google Analytics Tag Manager directly to Google Servers is forbidden by the GDPR law. Sidenote: To simplify this question, I intentionally leave out all stuff regards user consent management.
Problem statement: We have the need that each client sends every tracking event directly from the browser to a Pub/Sub endpoint. Now, my question is how a best practise for a proper security would look like.
Current proposal: The Pub/Sub endpoint doesn't require an authentication --> AllUsers have been granted Pub/Sub Publisher permission. In addition I've created an API-KEY that is restricted to
the Pub/Sub API only
to specific HTTP referrers (basically the domain our webshop operates)
Are there other strategies that could be applied? Is the current proposal a valid (aka secure) way to go?
Giving pub/sub publisher access to allUsers are not recommended. Create service account and give publisher access to that and send messages using that service account.

An IdP/STS for SaaS providers, where the SaaS customer does his own user management?

(This question is not about programming, but about how to avoid doing any programming. Also, lots of terminology in here-- I'm assuming someone with an answer will already know what they mean.)
Background: I'm working on single sign-on in an environment with 'federated identity'. We have several products that are federation-aware (using, e.g., WS-Federation or SAML protocol, implemented with, e.g., WIF on .NET and Fedlet on Java), and they are offered to customers using a SaaS model. Many of those customers don't have their own store of usernames/passwords, so they will not run an "identity provider" themselves.
Question: Is there a product out there that
can be installed at the SaaS provider;
plays the role of an IdP/STS (i.e., identity provider in a federated enviroment) to the SaaS-provided applications;
has its own username/password store, separately for each SaaS customer ("tenant");
allows the SaaS customer to do his own user management, without requiring assistance from the SaaS provider.
(We could build this ourselves, e.g., as a custom STS on top of WIF with user admin screens, but we're trying to avoid that. It's not really our core business.)
Have you had a look at Google app engine ?
They support SAML, so you can use them as your Idp.
So we did not find a product that fulfills all these requirements.
What we decided on was to use AD FS 2.0 as the SaaS IdP/STS, store usernames/passwords in AD (making the SaaS customer name part of the username), and customize the AD FS sign-in page linked to a custom web application for user management and user self-service.