we plan to introduce an API management solution and we're currently setting up a proof of concept with WSO2 AM. We want to use the WSO2 API gateway to check whether a certain consumer application is allowed to use an API and to throttle the request rate.
I work on the identity workflow and I wonder how a consuming application can pass a JWT token to the backend service with WSO2-AM in between.
First, this is our current scenario:
Without API gateway
The consuming application gets a JWT token for its carbon user from an identity provider. The JWT contains some claims about the user, e.g. the roles he/she belongs to.
The app calls the service an passes the JWT token in the Authorization HTTP header like: Authorization: Bearer
The service validates the issuer and signature of the JWT and retrieves the claims from it.
So, this is pretty straight forward. Now we put an API gateway in between the application and the service:
With API gateway
The consuming application gets a JWT token for its carbon user from an identity provider.
The consuming application uses OAuth2 to get an access token for the following API calls. We can use the client_credentials grant type and simply pass the the client id and client secret. I haven't yet tried it, but we could possibly use the JWT grant type (see https://docs.wso2.com/display/ISCONNECTORS/Configuring+JWT+Grant+Type) and use the JWT for passing user information to the API gateway.
The API gateway validates the JWT against the public key of the identity provider when using the JWT grant type.
An access token is returned to the app.
The app sends an API request to the gateway and passes the access token in the Authorization HTTP header.
The gateway validates the access token.
The gateway forwards the API request to the service.
And there is my problem: How can the JWT from 1/2. be passed to the service?
There is a documentation for "Passing Enduser Attributes to the Backend Using JWT" (see https://docs.wso2.com/display/AM210/Passing+Enduser+Attributes+to+the+Backend+Using+JWT), but this would introduce a new JWT, issued and signed by WSO2-AM, and I'm not sure, whether this JWT contains all information from the JWT used to create the access token (or even the original JWT).
Another way I could think of is using a custom HTTP header for passing the JWT through the gateway to the service. I cannot use the Authorization header (as we do without the API gateway), because WSO2-AM expects the access token in that header.
Since I'm not happy with either solutions, I want to ask the experts: How would you solve this?
Thanks,
Torsten
The only possibility I can think of is to send the JWT token in a custom Header for the backend service.
Related
I have ASP.NET Core RESTful APIs and protect them with JWT token issued from Azure Active Directory. Any client who wants to call the endpoints should first acquire a valid JWT token from the AAD and send that as a Bearer token. My API internally should call an external API (internal to the organisation) to query some information and return it to the user. The external API requires mTLS as its security protocol.
My questions
Can I still have my Bearer authentication scheme against my APIs and at the same time have mTLS enabled in my API so it can communicate with the third API?
From my understanding, in TLS which mTLS is an extension of it, the client should verify the server's certificate. Does that mean, with every incoming request I should check if it's presenting the certificate? If so, then what would happen to the Bearer authentication scheme then?
In my head, I was hoping that I can just append the certificate to the requests against the third-party API and that should be it but based on question number 2 I seem to be wrong about it.
I'm a bit lost here and appreciate any advice on this.
I'm auditing an API whose client is a mobile application using the OAuth2 workflow but I'm missing something. I have a first endpoint of the /token.oauth2 API which allows me with credentials to get an access token needed to call other endpoints of the API. So far OK but on top of that I have an "x-api-key" which is transmitted along with the access token and if both the API key and the access token are not present, the server sends me a HTTP 401 response.
I can't find any mention of a connection flow using both an "x-api-key" and an access token in the OAuth2 standard. When do you think?
I have an external endpoint which is going to hit the Azure API gateway and that would route it to the backend API which is protected by IdentityServer4 authorization.
I am getting the access token if I hit it through the Postman client with the interactive UI from IdentityServer.
Is there a way I can get the access token required from the Azure API Management to validate against the IdentityServer4 and append it to the header in the request to the backend API?
Yes it is possible to achieve it through custom policy. You can ask your external API-Client/Consumer to paas in credentials in heaser, and then you write a policy inside inbound to can read those user credentials and do a API request (similar to your postman) and get the access token. You can then append the same token and let your request gets forwarded to backend API.
As per your problem statement, this should work. In case not, you might have to explain your scenario with more description/steps.
Here are some of the reference materials for you, I hope it helps.
https://learn.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#SendRequest
https://learn.microsoft.com/en-us/azure/api-management/api-management-sample-send-request
Postman has a luxury of a human user seeing the UI and authorizing API access and IdentityServer4 to issue a token for Postman. There is no such luxury when call is being processed by APIM server, as you could send request for token to IdentityServer4, but who would be presented UI to authorize the action?
The only way is to provision some sort of secret to APIM (header, query, certificate) that would be recognized by IdentityServer4 to allow it issuing tokens for APIM. If such secred is available you could use send-request policy to make a call to IdentityServer4 and obtain required token.
Or make sure that every request to APIM has a token already.
I've some questions regarding authentication in a microservices architecture. I've right now a monolithic application and my goal is to split the application in small microservices.
My bigest problem is for authentication (for now). After reading a LOT a documentation, It seems that the best solution is to use OpenID Connect to authenticate an user to retrieve a JWT that can by passed with the request to the microservices.
Also, to avoid having multiple endpoints, you can deploy and API Gateway to have only one endpoint for the end user. Ok, so now I've two questions with this architecture.
The standard flow for authentication will be :
An user contact my identity server in OpenID Connect with the implicit flow and get the id_token (JWT) and also the access_token. The user can now contact my API with this access_token. The API Gateway will valide the access_token with the identity server and also retrieve the JWT to add it to the sub request to the microservice API.
1/ How the API Gateway can get the JWT from the access_token? From what I red from the documentation (http://openid.net/specs/openid-connect-core-1_0.html), It can contact the "/userinfo" endpoint but It will get just the JSON format not the JWT...
2/ I want to allow authenticated calls between my microservices. So each microservice needs to be able to generate a JWT to contact other microservices directly. My first thought was to contact the identity server. But with the OAuth2 Client Credentials flow, I don't retrieve a id_token or a JWT. Just a classic OAuth2 access token without JWT. My second thought was that the microservice can directly sign its own JWT with a certificate issued by the same PKI as the one used by the identity server. That mean that a JWT can be sign by several certificats but from the same private PKI. When a microservice receives a JWT, It needs to be able to identify witch certificat was used to sign the JWT. I don't find anything on the RFC regarding this problem. I can add my own private claim in the token to have the certificate but after several days of browsing the web without seeing this kind of solution, I'm wondering if I'm not on the wrong path... To sum up, how can i perfom "User to service" authentication AND alors "service to service" authentication in JWT?
Thank you very much!
I am implementing a similar solution. Not sure if it will address to your question completely, but, I hope it helps:
You can implement a new authentication micro-service to convert your oAuth2 access token to JWT token. This microservice will also sign this JWT token.
Your API gateway will route all client requests to authentication service, which will validate this token from IDM and will convert it to a signed JWT token.
API gateway will pass this JWT token to other microservices which will validate the signature from Authentication Service's public key. If the signature validates, roles can be extracted out of it for authorization.
Each microservice can have its own IDM credentials configured and when it wants to call any other microservice, it can generate an access token and call Authentication Service to get JWT which can be passed in call to other microservices.
We are current building a collection of back-end ASP.NET Core microservices. These services will not be accessed directly from the front-end application, but rather accessed through an ASP.NET Core API gateway. We are using IdentityServer4 for the OpenID Connect server. I have been able to setup the UseJwtBearerAuthentication middleware to have API gateway validate the JWT bearer token (access_token) against IdentityServer4. I would like to be able to have the API gateway inject the id_token, based on the access_token, into the requests made to the back-end services that may need to know the end-user.
Is there a way to configure the JWT middleware to retrieve the id_token when validation the access_token or do I need to manually call the OpenID Connect server in the API gateway?
You don't use id_tokens at APIs - they are for clients.
If you want to have access to certain identity claims, either include them in the access token (by configuring the ScopeClaims on the resource scope), or use the access token to contact the userinfo endoint which in turn will return the identity claims.
The JWT middleware performs standalone verification, it does not contact the identity server to verify or retrieve anything. You'll have to make an additional call.