问题
Context: I'm creating a cloud platform to support multiple applications with SSO. I'm using Keycloak for authentication and Netflix Zuul for authorization (API Gateway) thru Keycloak Spring Security Adapter.
Each microservice expect an Authorization header, which contains a valid JWT, from which it will take the username (sub) to process the request. Each microservice-to-microservice call should go thru Netflix Zuul first, passing the Authorization header to maintain a stateless validation. That strategy allow to every microservice to know who is the user (sub) who is invoking the microservice indirectly.
Problem/Question 1: What happens if a microservice is invoked from a queue message? One idea that I had is to storage in the queue the information related to the message + userInfo, and, create a dedicated microservice to process that kind of messages, with that approach this special microservice should read the userInfo from the queue and process the message.
UPDATE 1: Per an email reply from another forum, storing the JWT in a queue isn't a good idea, since it could be mined easily.
Problem/Question 2: But, what happens if the previous special microservice wants to call another normal microservice which expect to receive a JWT in a header? Should this special microservice create by himself a JWT to impersonate the user and be able to call the regular microservices?
Another solution that I thought was to storage the original JWT in the queue, but, what happens if the queue calls to the special microservice later? Just after the JWT is not valid anymore (it expired) and the microservice called will reject the request?
Possible solutions: (Updated per João Angelo discussion, see below)
I should authenticate the requests from my users (Authorization code flow) and my services (Client credentials grant), both requests should contain user information in the payload. When the request it comes from the user, I need to validate that the payload user info match with the JWT claims. When the request comes from a service, I just need to trust in that service (as long as it is under my control).
I will appreciate very much your help. Thanks.
回答1:
Disclaimer: I never used Keycloak, but the tag wiki says it's compliant with OAuth2 so I'll trust that information.
At a really high-level view, you seem to have two requirements:
- authenticate actions triggered by an end user while he's using your system.
- authenticate actions triggered by your system at an unknown time and where there is no requirement for a end-user to be online.
You already met the first one, by relying on a token-based authentication system and I would do exactly the same for the second point, the only difference would be that the tokens would be issued to your system using the OAuth2 client credentials grant instead of the other grants that are targeted at scenarios where there is an end-user.
(source: Client Credentials Grant)
In your case, Keycloak would play the role of Auth0 and your client applications are microservices which can maintain client secrets used to authenticate themselves in the authorization server and obtain access tokens.
One thing to have in mind is that if your system relies on the sub
claim for much more than authentication and authorization then you may need to make some adjustments. For example, I've seen systems where performing action A required to know that it was targeted at user X and Y, but the payload for the action only received user Y and assumed user X was the current authenticated principal. This works fine when everything is synchronous, but by merely switching the payload to specify both users would mean that the action could be done asynchronously by a system authenticated principal.
回答2:
One common setup is to have an API gateway that verify all incoming requests by their JWT. The API Gateway validates the signature of the JWT (or decrypt it for encrypted JWT's), checks the the expiry time etc, and extract the scopes and the User ID (sub) from it.
It then compare the scopes with a set of defined scopes for each micrto service, and if the scope provides the user (subject) access, the request is forwarded to the micro service. The User ID (sub in the JWT), along with other needed information stored in the JWT is placed in custom requests headers like X-IGNACIO-SUBJECT
来源:https://stackoverflow.com/questions/40458770/microservice-to-microservice-calls-authorization-from-a-queue-message