How to make available the identity of a user across multiple microservices? - authentication

So let's take the basic e-commerce microservices.
Identity and access . This microservice will take care of user accounts, roles
and authentication. The authentication method will be the based on the usual
token based flow (user enters username + pass and server returns a unique and
random token via cookie). This service can also be used to get the user profile.
Cart microservice. This microservice can be used to put products in a cart.
Check what products a cart has. Etc ...
Asuming that "Identity and access" microservice will be used for generating the random token as a result of a succesful authentication, and for linking this token to a user, how will this token be used to make the user's identity available to the cart microservice? For example, when a user will add a product to his cart, he will send along the authorization token and the cart microservice will have to identify the user based on that token.
Could a distributed database be an option? A database which has these tokens stored and links to user built, and to which all microservices have access?
Or should all microservices get the user's identity from a special identity and access API which will expose users based on the access token?

A distributed data base definitely conflicts with the following basic principle of micro services:
A micro service owns its data and exposes it via well defined interfaces.
No other micro service may access data owned by another micro service directly.
So one solution in this case would be to have a token micro services or the last solution you have described.

Related

Centralized Auth server or One db per microservice for users?

I'm designing two micro services one for Teacher and other for Student. Now my question is what is the best approach of storing users and doing Authentication Authorization :-
Centralized Auth server which will store user roles as well as all the info.
Centralized Auth server which will only store roles but the user info will be Stored in the databases of their respective services (Student, Teacher)
No centralized Auth server but redirecting login request to either Student or Teacher as per the role in the request body and it will be the responsibility of Gateway.
I want to know the pros and cons of these approaches. If there is any better approach then please share the same.
P.S :- Multiple roles can be assigned to a single user.
I would go for the first approach. Rather than "centralized Auth" server it would be more of a "auth micro service".
Now the important part is how to handle authentication itself. In general you could either use a session or JWT.
For micro services I think JWT is a perfect fit. If you use session you basically "centralize" your authentication and authorization. What I mean by this is that after a user is authenticated, every time the user makes a request all the micro services that react to this response must check on the centralized session. This will not only increase latency but it just doest fit with the distributed system. The point of using micro services is to have make replicas of services and so scale horizontally.
If you use JWT, the micro services only need the secret key to validate the token. Basically no centralized store(session) for authentication infos.
About the "auth service", I would suggest you to store authentication and authorization related data only(including user info related to authentication. phone number, email, name etc. you probably would use this in case user needs to change password, forgot password etc.). Other specific data related to a specific role can be stored in the corresponding service.

Best OAuth flow to allow customers to access my SaaS application

I have a SaaS application that has multiple organisations and each organisation has multiple users. Each customer is an organisation (not a user) and the customer wants access to their data in my SaaS application via API. Obviously I need to authenticate the customer so they only receive the data that belongs to their organisation.
The customer will be importing this data from their application so this is a server-to-server API call which I assume I need to use client credentials flow.
The customer will be able to generate the credentials on a self-service basis.
Is using client credentials flow the correct flow?
If using client credentials flow does each customer have their own client_id and client_secret or does my application have 1 client_id and each customer have their own client_secret?
The standard solution for this type of B2B API solution is to use Client Credentials flow as you suggest.
Each business parter uses their own client id for identification when calling your API
Each partner is also given a string client secret - though it may be possible if your authorization server supports it to use secrets based on an X509 credential
Use of different client ids enables you to turn off Partner A without impacting PArtner B - and also to tell callers apart
Authentication completes based on the client id and secret being verified and you then move onto authorization. Typically your API will need to continue by doing this:
Receive a technical client id such as 08134scdv79
Map it to an application specific id, such as a primary key from your Partners database table
Authorize the request based on whether the caller is allowed to get the data requested
The one interesting aspect to your question is the self service part. I assume you mean some kind of administrator from a business partner can set up credentials - but that this remains a restricted operation?

AWS Cognito combined with other Rest apis except api gateway

Cognito is a powerful tool yet it's so hard to utilize it .
Trying to implement my business logic I ended up in some dead ends and I need some help.
My client app is an admin panel where a new admin can register providing a company.
Now there are 2 applications (Contests, Reviews) based on these companies .
So from the adminPanel the admin can create events for both apps through 2 different rest apis
The concept is 1 admin is related to 1 or more companies.I have to map that relationship somehow with Cognito .
Because cognito does pretty much well authentication but not authorization.
In every request not only I have to validate the user by the access token but I also have to see if the user is authorized to do the action based on the company.
For example if a user want to create a Contest event for his company.
I will make a request to Contest Api and I have to authorize that the admin is related to this company
Company entities are used from both apis so I have to expose them in a new api called companies.(If any api wants information about companies it should call the get company/{id})
My consideration is that in order to authorize a user in my apis I have to:
1) validate the access_token .
2) communicate with Cognito to get user informations.
3) call companies api to check if user is authorized to execute actions for this campaign.
So I kind of feeling that it becomes too complex and I need 2 services to authenticate and authorize each request(cognito + company api).
Is there any other way to implement cognito authorization logic without having to use a second api ?
P.S I have already check cognito triggers but they don't cover my needs .For example pre token generation trigger can add claims but it will add them in identity_token not access_token .Also my claims has to be an array of company_ids that an admin is related but claims supports strings and numbers only

IdentityServer4 personal access token (github-like) or API key for third party clients

Our current setup is
IdentityServer4
Angular + ASP.NET Core application
Authentication for the app via implicit flow/oidc.
We want to provide APIs for customers, i.e. third party clients, with restricted access (separate set/subset of claims). These clients are mostly non-interactive scripts that download data.
This means that we cannot use any flow which (occasionally) requires user interaction. Personal access tokens, like in github, or some other generate once, reuse for a long time API key or token would be needed.
The long token lifetime would not be a security issue, because the token should only allow access to a few read-only APIs and only for that customer's data - so the responsibility to handle the token(s) falls onto the customer.
The customer should be able to create and revoke such API-access tokens based on their claims. Some users might only claims to access certain APIs.
It would be good if we could later prevent that the user re-uses the same token for multiple clients because of licensing requirements but that is perhaps an entirely new question
How could I achieve this?
I thought about doing this via a custom grant, similar to a delegation grant: user uses app, which calls the asp.net core API, which performs auth with that custom grant, persists that token somewhere (just a plain table in the database full of customer-api-only tokens? I'm not sure about that) and shows it to the user - which can also retrieve it later from storage.
I'm thinking about doing the "delegate"-authentication via our API so that we don't leak the secrets into the Angular application.
I think that we then should be able to have either long-lived access tokens or at least refresh tokens via that custom grant.
2017-12-12 how I think I could solve it
We want a process where the user generates something in our application (i.e. via our client) and this something can later be used by the user's third party client to access the API - or request an access token and then access the API.
We want this access to be tied to the user. This includes
- Disabled user
- Lockout
- Specific claims (e.g. tenant)
This does not lend itself well to a solution that issues access tokens directly, because the token would remain valid even if the user was disabled or locked out. Which means that we cannot use a custom grant or IdentityServerTools to issue tokens directly.
Therefore we should use the client credentials grant, or something similar to it, as this could yield new, short-lived access tokens.
User actually generates a new client, which is pre-filled with claims from the user (such as the tenant - which is immutable) and has a claim that corresponds with the user. This happens transparently. Password should be user-supplied with the option to change it. We only store the relation between user and issued client-ids, no passwords.
We have to create a custom grant, which works similar to client credentials, but also checks if the corresponding user is active etc. (which I think should be possible by injecting UserManager)
Resulting access token lifetime is short, interaction with our APIs is expected to be short-lived.
Assuming it is safe and easy enough to write such a grant, we should be able to cover everything we need.
Of course, I might have completely overlooked something :)

IdentityServer 4 and scope specific user settings

I plan to use IdentityServer 4 on ASP.NET Core with ASP.NET Identity as the data store. This is the first time I use a central authentication/authorization and I am wondering how to solve the following question:
Assume I have users with claims like name, role etc. and a Web API (scope) that allows these users access to measured values from hardware devices. IdentityServer will allow me to authenticate known users but now I need an access control that knows which users may access which device data.
Where do I store this information? Since it is specific to the scope I guess it should not be stored in the IdentityServers store. On the other hand, if I store it in the scopes own database I somehow need to connect it to the users defined in the IdentityServers store. Should I define user IDs that are unique to all scopes and IdentityServer?
You will need to correlate the User Ids that IdentiyServer returns with users defined in the scope's database.
I believe that there is a User table and a UserLogin table where you could track the different logins for each of your users.
Then, in the scope's database, you can then specify which users have access to what device data.
This is a bad idea and will probably lead you down a road that you should not.
This means that your client application requesting the scopes will need to know which user has access to which scopes even before requesting a token from your IDP (otherwise your token request will not work). Rather model these as user claims. Then on your WebApi you can do normal claim based authorization.