If my services communicate over Sync HTTP I would pass the JWT token to each service so each service an authenticate the request and ensure it is only providing data for the authenticated user.
However, if I change my communication mechanism to using async messaging (e.g. RabbitMQ), how would I now authenticate the event to the scope of the user who initiated the event. Should the same JWT be passed as part of the event message. I see an issue with this mechanism, in that the JWT may have expired by time the service processes the message which means the message will not get processed.
Is this the general approach and best practice, or should some sort of trusted policy be created and passed as a alias to the original JWT stating what that user could do and had access to, or is there a different approach?
Once the user invokes the first microservice you should trust the communication among your services, so you dont need a jwt or standard token. You can pass in the event some sort of identification of the original user or its scopes to ensure that the reciever service filter the information accordingly.
This identification can be even a jwt token without expiration because it will be a token that only is used internally among your services so there is no risk that a malicious user tamper it.
Related
My architecture considers an ApiGateway (ApiGee) that dispatches requests to a service behind.
All APIs (http and rest) have an authorization mechanism. So, the client needs to authenticate itself to an IAM before operate with my APIs.
In order to avoid bad security design, all services behind the ApiGateway accept authenticated requests.
For (technical and business) requirements reasons, I need to use internal/external different authentication mechanisms: when a client sends a request, that has to contains the authorization information provided by IAM1. Instead, the services behind accept authenticated APIs that contains Auth information that came from IAM2.
For the translation, I create a service 'translation-token-service' that exposes an API for implementing the token translation.
My desiderata is to "link" ApiGee to the 'translation-token-service' in order to let the clients to continue to use the authorization from IAM1 and the behind services to continue to use the authorization information from IAM2: when a request arrives, ApiGee should invoke the 'translation-token-service' for having a token with IAM2 authorization information, injects them into the request and dispatches it to the right behind service.
NB: the token conversation made by ApiGee should be in some how cached (I don't care about the storage type). So if a client makes two call with the same token, the first invocation asks to convert the token, the second one doesn't, for performance reason.
NB: IAM1 is not oidc compliant, IAM2 does.
How can I implement this flow?
I found one interesting article that has this illustration:
It says that:
API Gateway verifies access token for all incoming requests via introspection
But what does this mean?
it says that gateway goes to authorization server and validates token (JWT).
why is that needed?
if gateway has authorization server's public key, it can check token validity using signature just like every backend service, why is introspection needed and how is it done?
Depending on your Identity provider it can be done either way but there are trade offs.
If you validate the token locally then yes it can use public keys to do that and that's very efficient way, however downside is that if the token or signing keys are revoked then your token is still valid. With Remote check you have to bear the http overhead but that is more reliable.
Normally tokens are kept short lived and validated locally. But if your access token are long lived, your application require strict access controls or library doesn't support local validation then it's a good idea to check them remotely
I believe you are looking at this document.
What I understood from this Secure API Gateway is that the gateway is responsible for introspection and the back-end services will only check the token signature, which is less secure than introspection, but still a layer of security.
Introspection is necessary to validate the token information against the Authorization Server.
This is more secure, because the system can ensure that the token received is not malicious, expired and it is from an known source.
The details on how it is done are explained in RFC 7662.
Yes, the gateway could validate the token signature if it has access to the certificate.
I can't really tell why they choose the back-end server to do it, probably a project decision.
API Gateway primarily meant for routing the incoming calls to the corresponding MicroService Clusters.
In addition to that,it can also play a role to validate the token, so that only valid traffic is routed to the downstream servers (filtering malicious traffic).
The level of validation could be up to the product owner/architect decision. It could be as simple as validating against the list of in memory cached token or in depth validation on set of claims, digital signature verification, expiry time, audience claim etc.
You can view the set of claims inside the token using JWT decoder like https://devtoolzone.com/decoder/jwt
I have multiple services:
User
Post
Comment
Authentication
GraphQL endpoint
And let's say they are connected together like this:
All services are communicating through gRPC on a closed nettwork and the Authorization is done using jwt tokens
Approach 1:
The graphql service is responsible for user authentication and making sure that the user is authorized to run the specified procedure. There is no user authentication between the services, but there is TLS authentication. There are no authorization checks done by the services.
Approach 2:
Each individual service makes sure that the user is authorized to run a specific procedure. An example could be voting on a post where you would need to be signed in and have over 15 in reputation. Here it would be the Post service's responsibility to check whether the user is signed in or not (authenticated) and whether it's authorized to vote. This will result in large overhead since every procedure call needs to check user authentication and authorisation through the Auth service.
Is there a better approach that still preserves the security of approach 2, but creates a small overhead like approach 1?
-----Update-----
Approach 3:
Same as approach 2, but user authentication is only done in the GraphQL service using the Auth service. The authorization is done by checking metadata passed around. And there is TLS authentication between the services.
Let's consider a request that travels from the authenticated user to service A and on to service B. The JWT should be passed on each of these calls.
Both services would first authenticate the user which is simply done by validating the JWT. Then each service would extract all information necessary to authorize the user from the user, for example the sub claim. It would use this information to decide if the user is authorized with respect to the operation that the service shall perform on behalf of the user. Only after successful authorization would the service actually do anything.
This would not be overhead but necessary to allow service B to both authenticate and authorize the user. Not passing the JWT from sercice A to service B would make it impossible for service B to know anything about the user.
I am designing a service oriented application where the communication to the database is distributed across multiple services (Authentication service, some service for auditing and other for accessing the db and doing CRUD operation ... etc).
Say a user login to the app using his id and password, the app then talk to the auth service and find out if the information are correct, once done the user want to insert some data, now the app use another service to fulfil the user request. How can the other service now that the user is an authorized user to use the service.
Your use-case seems very similar to what SAML addresses.
Also look at OAuth.
If these standard mechanisms don't work for you, you can at least develop a mechanism where:
The authentication service returns a token on successful login. The
caller app should then be able to use this token to access the data
service and other services.
The data service should be able to independently validate the token (possibly with the authentication service).
You might want to ensure that the tokens remain valid only for a certain duration or certain number of invocations
What this avoids is the need for every back-end service to allow access to the app without using your login details.
Also see: What is token based authentication?
So I've been banging my head against the wall for the past couple days trying to understand how WCF's security architecture worked. I have a goal in mind and I'm not sure that I'm going in the right direction.
The System
We use a combination of Active Directory and databases to manage our authentication and authorization. Client applications typically use their Windows credentials to authenticate and the applications checks against database tables to see if those users are allowed to authenticate and then if they are authorized to use the resources they are requesting. The current setup has each client directly communicating with the database to do these checks.
The Goal
We want to use a Security Token Service to authenticate the client and provide "high level" authorizations for top level resources. The services that provide data or perform actions would operate if the supplied SecurityToken was valid. Additionally, the token, if it did not contain a particular right, would query the token service to see if the user did have rights that were not loaded when the token was initially created. (We have over 300 rights in our database, and that could lead to rather hefty tokens for users with many rights)
What I Don't Understand
1) I understand the token creation process, but I'm a little lost on how the client gets, stores and sends the token to the services it intends to use. Does each "worker" service require a unique token (i.e. call to CalculatorService requires one version of the token and the SaveResultService require a new token to be generated?) Can I manually request, save and send tokens?
2) On the "worker" service side, what is the process by which the token is verified? Does my "worker" service have to contact the Token Service for verification of the token? Or does it just read the token and assume, if it is properly signed, that the token is genuine and operate from that perspective?
3) Is it possible to encrypt my tokens manually and store them on the client side for use while they are valid (thus avoiding authentication attempts on every service call) and so that a web client can save the token between page loads and reuse it on successive calls?
Thanks for helping with my lack of understanding
You should go through the samples for Windows Identity foundation - It providers the classes and implementations required to wrap claims that you can use or query for auth and authz.
http://msdn.microsoft.com/en-us/library/ee517291.aspx
What you are looking for is a durable token cache. - Tokens have lifetimes and usually require renewal and WIF does the renewal under the hood for most scenarios.
You can manually request and attach tokens and pool the proxies using WIF.