How to pass a parameter from a URL to an auth0 hook or rule for a machine-to-machine JWT? - jwt

I'd like to add a custom claim to a JSON web token generated by auth0 for machine-to-machine authentication. Like
color:blue
but I want to make blue a parameter I can pass with my request to auth0 for the token.
I ask for the token like this:
POST https://mydomain.eu.auth0.com/oauth/token
with a request body
{
"client_id":"myID",
"client_secret":"mySecret",
"audience" : "https://mydomain.eu.auth0.com/api/v2/",
"grant_type" :"client_credentials"
}
I see from How can I add claims to a JWT assigned with auth0 for a machine-to-machine application type? how to use a hook or rule to add a fixed claim, but I want to add a variable something like
?color=blue
to my request URL or request body and have that accessible from my hook code to be added as a claim.
Is that possible, please? How?

When you process an authorization request with a custom rule you get access to at least a part of the request properties by the request object of the context function argument. I tried it out but unfortunately the fields of the request object seem to be limited to only a few fields of the original request.
If your user information resides in Auth0 you could check out writing preferences into the user's metadata by using the Auth0 metadata API. This works well. But you will be able to only set metadata after the user has logged in, not before. Also you'll have to deal with two different Auth0 API endpoints now.

Related

REST API Design: Should I use a custom header or Authorization for some sensible information?

this is my first question on StackOverflow. 😀
I'm currently creating a Discord Bot with a Dashboard and a private API for my service.
The flow I'm trying to create is the following
User logs in with Discord OAuth2 and gets his access_token
-> Client stores his access_token
-> When doing an action on the Dashboard and commit it, make an API call and pass his access_token
-> My API then check if he has the permission to commit it
(by doing a request to Discord's API with his access_token)
-> Realise the action if allowed
Because the user needs to send his access_token, I need to know how I'm supposed to recieve and use it safely, and following the best practices.
Those are the two way I found :
Use a custom HTTP Header like Discord-Access-Token: <access_token> and then process-it easly
to use Authorization: Baerer <access_token> (even tho this is not
an Authorization but something I need to check if the user is allowed
to use the API). + This is not really following the flow in FastAPI...
Does someone knows what is the best thing to use? Thanks in advance!
even tho this is not an Authorization but something I need to check if
the user is allowed to use the API
So Authorization in simple terms...
Think of your service as something that covers everything you do even doing stuff with tokens on Discord.
I would use the Authorization header, because it is standard, unless you have another token, because you cannot send multiple ones in a single request except if you package them together. If you have a different header, then the request can be modified or cached by proxies. https://stackoverflow.com/a/43164958/607033
As far as I understand Basic and Bearer are not the only types of Authorization, you can have a custom type too. If Bearer does not cover the term you need, then write something like DiscordOAuth2.
The Authorization header name is a misnomer, in the same category as the misspelling as 'Referrer'. The purpose of the Authorization header is actually authentication.
Also not that it's Bearer not Baerer.

How are token claims accessed in an action invoked by an API call

Scenario: user logs in using App ID via my app (android). The app makes an API gateway call that invokes a function. The function needs the identity of the user (i.e. the claims of the identity token). The function is IAM enabled and the API is secured by App ID.
When invoked, the function params and environment variables do not include information about the authorized caller. Params to the action do include an authorization header, but when it is decoded it is the header to the function invocation, not the header from the API call. Environment variables do not include the information either.
I have this working on AWS but I have not been able to discover how it is done on the IBM cloud. I suspect a parameter needs to be set on the action but I have not discovered the variable needed to do that. Is there a list of variables that can be used to set parameter values?
What I am expecting is a way to get the API gateway to forward headers (i.e. authorization) from the API call to the function invocation where I can extract the claims.
Making the API request with the authorization header set to the users identity token rather than access token fixed it. The params received by the function included the identity token claims.

How to restrict a user to THEIR resources using JWT when there is no identity in the Access Token?

We have a REST resource like this:
/customer/{customerId}/bill
We want to use the JWT tokens returned from AWS Cognito to secure access to this resource.
The {customerId} here is not the Cognito user id, it's a domain specific id. We have added this domain specific id to the Cognito user as a custom attribute. It comes in the ID token that Cognito returns like this:
{
"sub": "xxxxxxxx-852f-474d-aa9e-a50fd832bcb8",
"aud": "xxxxxxxxsijed6uf54dh0uhi",
"custom:customerId": "4044",
"event_id": "xxxxxx-fc0c-4ffc-affa-f8987714fb2b",
"token_use": "id",
....
}
If we use this ID Token in Authorization: Bearer <ID Token> we can write code (custom authoriser or in-app code) that ensures the customerId in /customer/{customerId}/bill is equal to the value of custom:customerId in the supplied token, and we have secured our API.
But then we read that you should not use ID tokens to secure APIs . The key point being:
"The audience (the aud claim) of the (ID) token is set to the application's identifier, which means that only this specific application should consume this token."
So it seems we need to send an Access Token to secure the API. With Cognito, there is no way we can add any concept of who the user is into the Access Token. We can't add a custom scope like user:4044 for example.
What folks suggest as an approach here is to call the /userinfo endpoint of Cognito on the server-side with the supplied Access Token to learn who the user is. This would enable us to write code (custom authoriser or in-app code) that calls this endpoint and asserts permission. But it's an endpoint call for every request, which seems crazy.
One thought that crossed our minds was to use the Access Token to secure access to the API itself, but also require the ID token, either as a query parameter or a header to allow us do the fine grained access control. But that too starts to feel wrong.
Surely this is a solved problem? What is the right thing to do here?
Sorry, this question is a year old, so my answer is probably irrelevant. But for future wanderer, I would say that, given the limitations of cognito in allowing custom claims in the access token, a call to the /userinfo route is definitely the best way.
The API GATEWAY lets you cache authorizer response for a given user, so you won't be calling the endpoint on every request. Note that some implementations recommend it as a way to make sure that the token haven't been revoked.

How to download a file secured with IdentityServer

I want to be able to download a file from an API call. For argument's sake, let's say it's an automagically generated PDF file.
I have two problems:
Anchor tags can't add Authorization headers to the request, only XHR can.
XHR requests cannot download files.
My solution is to write my API with an [AllowAnonymous] end point in it, which takes the access_token as a parameter. I then validate the access token by hand and return a 401 or stream the PDF.
Is there a better solution than this or, if this is the best solution, how do I validate the access_token within the API?
This approach is totally fine.
If you want to use middleware to validate the token - it depends which middleware you are using. The plain Microsoft JWT bearer middleware has some events you can implement to retrieve the token from a query string alternatively.
The identity server token validation middleware has a TokenRetriever property which also allows you to retrieve the tokens from multiple/alternative locations.

Implicit flow, but requires access to multiple API's

Say I have a website secured with IdenityServer3. It uses the implicit flow so users are asked for their credentials. Now I'm facing a requirement where this application should access multiple (Web)API's on behalf of the user. These API's are secured using roles.
How do I go about this? Do I get one access_token for all by adding "token" to the ResponseType of the OpenIdConnectAuthenticationOptions? Do I have to change the Implicit flow (to Hybrid?) and manually request access_tokens for each individual API and add those to the user's claims, after authentication?
I'm not sure on how to approach this. Any help would be greatly appreciated.
You can keep using Implicit flow and add "token" to reponse_type (so it becomes "id_token token"). That will give you access token as well. Additionally, you can specify any scopes that those APIs might require in order to include claims that might have to be present for API Authorize attribute to allow the call through.
Once you have the response from IdentityServer in your application along with access token, you call the api with that token in the Authorization header.
I was able to resolve my requirement by moving to a Hybrid flow. For the response type I ended up needing "id_token", "token" and "code". I also had to retrieve the user claims manually in a separate request and manually add them to the user's identity, because adding "token" besides the "id_token" would remove all claims from the server response (to keep the token smaller).