How to download a file secured with IdentityServer - identityserver3

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.

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 to pass a parameter from a URL to an auth0 hook or rule for a machine-to-machine 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.

Tracking consumers for RESTful API (no auth)

Folks,
What is a simplest way to track consumer applications accessing RESTful API services inside department.
We do not restrict access - no authentication/authorization - open for invocation, trusted environment.
No tools like OAuth AuthZ servers or API management yet... but might be heading there at some point.
For now we thought to request consumers just to include some custom HTTP Header like X-Client-Id and log it on the server side for stats etc..
But knowing that in the future we might want to switch to more standard ways of doing things ... what would be best alternative to have to change less code in the future ?
Have the "clientId" in the Authorization: OAuth token (like access token)
Have JWT token in the Authorization header (looks too much - signing,base 64 etc for simple client id tracking ...)
Any ideas would be appreciated
We recently implemented this for one of our REST platforms and we used a combination of BOTH the points you mentioned, meaning Authorization header & JWT token. Although, JWT is ONLY for authentication and GETTING an access_token (oauth token) which is later used with calling actual resource apis. I will discuss how we handled this situation and you can decide on how you want to implement it.
1) Authentication
Client sends a JWT to your authentication service (/api/oauth2/auth). (If you want more reading on JWT, you can read here and here of how JWT is implemented by google and how you can use spring-security-jwt libary to handle all the signing and encrypting/decrypting). You get the "clientId" out of JWT after decrypting and verifying the signature and after server does all the authentication, you respond back with a 'refresh_token' and an 'access_token'. Server will save the access_token as well and map it to the clientId so that when client makes requests using access_token, you can know which client is making the request. The access_token expires in some time (ideally in an hour) and when it expires, the client uses the 'refresh_token' to get a new access token by posting refresh_token to some refresh token url (/api/oauth2/auth/token)
2) Authorization
Client takes the 'access_token' and uses the access token to make all the subsequent requests on all other apis (/api/*). Ideally, the access_token is sent as a part of the "Authorization" header. Server uses request filters (if you are using JAX-RS, you can use something like ContainerFilterRequest to add filters to specific url patterns and intercept them) to filter EACH request and parse out the Authorization header value. You will get the access_token from the header and from the access_token you can get the clientId that you mapped in step 1). You can do other authorization logic in the security filter and if everything goes through, you can use this information to LOG that clientId and the request that the client made.
This way you can kill 2 birds with one stone : Implement a security layer & log the information about customers (what calls they are making, how many time etc. etc.). In case you don't want to implement security filter just yet (as you mentioned it might be in the future), for now, the clients can just pass on the "clientId" (base64encoded or not, upto you) as a part of "Authorization" header. If all the calls are from a "trusted" network, it should be ok, although not as secure. This way, when you ACTUALLY implement a JWT and Oauth based security layer, all you have to do is change your ContainerFilterRequest logic to parse out access_token instead of client id (as mentioned in step # 2).
I hope this helps ! For more information on security filters you can have a look at this answer: Basic Authentication of a resource in Dropwizard. It says dropwizard, but it mostly talks about JAX-RS.
To implement full AuthN/AuthZ layer for consumer tracking would be an overkill for now.
We thought to use either to Authorzation header to pass custom client_id token:
Authorization: Custom <Client_Id>
or to use some limited version of JWT (no signatures as there no intent to validate them)
as access token
Authorization: JWT <JWT>
Where JWT could be:
{"alg":"none","typ":"JWT"}
{
"iss":"Client_ID",
"aud": REST Service URI,
"iat":1328550785
}
I do not see description of access_token format in the specification https://datatracker.ietf.org/doc/html/rfc6749#section-1.4
Are there any contraints to use JWT as access token?

Is there a standard way to generate a RESTful access token?

I just touch with RESTful API. Basically, no matter what the rest api is, the first step is to get access token. However, I have been in two different situations:
Have client_ID, Client_secret, and username, password.
POST: api.XX.com/1/authorize?
Authorization:Basic [client_id:client_secret] must be base 64 encoded
Content-Type: application/json
Then, I get access token without timeout.
Have app_key
GET https://api.XX.com/authorize?
response_type=Pin&
client_id=APP_KEY&
scope=SCOPE
After get Pin, register in web application. Then use code to request access token.
POST https://api.XX.com/token?
grant_type=Pin&
code=AUTHORIZATION_TOKEN&
client_id=APP_KEY
Finally, I have access token and reflesh token. access token will be timeout after 1hr.
So I need to use refresh token application access again.
I just want to say, Even the RESTful doesn't have Standard, access token application methods are big different. I think the first one is better. The first one makes things simple.
Because I just start to call RESTful Web Services, I would ask:
Are these two authorization methods common way? Is there a third method to get access token? Any comments please. Thanks.

CSRF token generation in GWT RequestFactory based app

including a CSRF prevention token in POST requests and validating it on the server by overriding DefaultRequestTransport and RequestFactoryServlet seems to be simple enough.
However, I have one remaining issue: How can I generate the token and get it to the client the first place?
It is quite possible, ney likely, that I have missed something obvious. I am assuming that I need to create the token when the session is created on the server, store it in the session and pass it to the client.
The client then stores the token in a cookie and passes the token in request headers from that point onwards.
Is there a filter of some sort which I can use to provide the tokens?
If you were using RPC, you can read this document, it has example code for implementing it.
For RF, this question could be helpful.
The server generates a random token on the first request and typically includes it in the download of the script.