How to indicate the authentication URL in OpenAPI 3.0? - openapi

Defining a Bearer authentication scheme in OpenAPI 3.0 is straightforward:
components:
securitySchemes:
bearerToken:
type: http
scheme: bearer
But this doesn’t tell the API users how to actually get a token.
Is there a way of saying ”you need to provide a token in order to use this API, and you can get one by doing a POST request at /api/auth with fields login and password”?
(I guess I could document the auth endpoint, but then I would have to drop the global security property and instead put it under every endpoint except that auth one, right?)

You can still have the global security setting be token auth, and then override it for /api/auth to allow un/pw combo for token generation

Related

Property header for firebase auth token api request to a custom server

I have a project including both a frontend (made with Vue) and a backend (made with Node.js). My server handles all the frontend requests and has its own mongodb. I am using firebase only for the authentications.
My problem is this: how can I make the server sure that a certain request is sent by a logged in user that has the privilege to do that request?
For instance if I have the request POST /user/:uid/products, that makes a user add a product to its account, I want to be sure that it was the actual user that made this request.
I came up with this: https://firebase.google.com/docs/auth/admin/verify-id-tokens#web, getting the user token from the frontend and checking it in the server through the firebase admin api.
I just want to know which is the right header where I should put this token. I mean, should the frontend put the created token in the "Authorization" header? Which header is the most appropriate?
It's customary to put it in the "Authorization" header, just as you said.
Typically the header is formatted like this:
Authorization: Bearer <token>
This is documented in the OAuth 2.0 Authorization Framework: Bearer Token Usage, section 2.1. Your backend should of course parse the same format.

Keycloak - Retrieve JWT token via OIDC Endpoint

I'm currently trying to retrieve a user token from the keycloak token endpoint using a POST request (instead of using one of the designated adapters). I have set up a keycloak realm and added my own machine as a client. In the documentation the Token Endpoint is described as:
/realms/{realm-name}/protocol/openid-connect/token
As far as I have read in the openid specification, I will need to set the body parameter grant_type=authorization_code as well as the parameters code and redirect_uri. I will also need to set the Authorization header, for which I will need a Basic Token.
So far I will get the response:
"error": "unauthorized_client", "error_description":
"INVALID_CREDENTIALS: Invalid client credentials"
Where do I get the Basic Authorization Token from? I expected that I need to provide a username and a password, since the JWT token is what I'm trying to recieve as response. Do I need to set the redirect_url if I just want to request a token?
Keycloak offers more than one way to retrieve a user access token, following the OpenId Connect spec. Here you have the steps to do it for Authorization code flow (the one recommended for web applications) according to the openid connect spec: https://rograce.github.io/openid-connect-documentation/explore_auth_code_flow
Basically, if you're not using any adapter, when detecting a request to some protected resource you should:
Perform a redirection to the keycloak login page (keep in mind keycloak uses the REALM entity, so you'll need to specify it too):
HTTP/1.1 302 Found
Location: https://mykeycloakinstance.org/auth/realms/demo/protocol/openid-connect/auth?
response_type=code
&scope=openid
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
You'll need to keep the state value in the client, as it needs to survive the redirection process:
It is recommended that client’s use this parameter to maintain state
between the request and the callback. Typically, Cross-Site Request
Forgery (CSRF, XSRF) mitigation is done by cryptographically binding
the value of this parameter with a browser cookie.
You don't interact with username/passwords. The keycloak authentication page does. Once the login is successful, it will redirect to your page with a valid code:
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
Here you'll need to either check that the state is the one you originally sent (you may need to track it through web session, using cookies) and also to obtain the token using that code. You do a POST to the authorization endpoint with this code:
POST /auth/realms/demo/protocol/openid-connect/auth HTTP/1.1
Host: https://mykeycloakinstance.org
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
This is the flow in summary, I haven't tested the code myself, so use it as an example and don't hesitate to fix it if you consider ;-)
See also:
What are Keycloak's OAuth2 / OpenID Connect endpoints?

Password Grant Types, standard way to pass username and password

In Oauth 2 Password Grant Type, when retrieving the access token, where should I pass the parameter like username, password and grant_type?
Is it as query param, in body or in header?
Following OAuth 2.0 rules you'll pass them in the HTTP POST request entity-body using the application/x-www-form-urlencoded format.
Additionally, if the client application was issued client credentials in the form of a client ID and client secret you will pass those in an Authorization request header using the Basic authentication scheme.
This is stated in section 4.3.2 of the specification.
The client makes a request to the token endpoint by adding the following parameters using the "application/x-www-form-urlencoded" format per Appendix B with a character encoding of UTF-8 in the HTTP request entity-body.
For doubts around the exact syntax of the requests you should always refer to the spec. For additional information, example code, you can always refer to the documentation of identity providers, like Auth0 and/or Google that implement these protocols.

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?

Basic Authentication with a Guid token for REST api instead of username/password

Overview
I am developing a mobile application using PhoneGap with REST API for the backend. The REST API won't be utilised by third-party developers, but will be application-specific, so there is no need for oAuth to be implemented. Hence, I am planning to use Basic Authentication where in the User enters their Username/password to access the API resources. All API communication will be on SSL.
Basic Authentication with Token
Instead of letting the application store the username/password and send it with every request to the API, I would rather authenticate username/password on the first login request and send a GUID token back. The client stores this GUID token and sends the token back to the API with each request through the Authorization header, like this:
Authorization: Basic e1d9753f-a508-46cc-a428-1787595d63e4
On the server side, the username/GUID combination will be stored on the server with a expiration date along with device settings. This will allow to keep track of the number of devices a user has logged in from as well as expire the session once the Guid has reached expiration.
Does this approach sound reasonable and secure?
There is no need for you to create custom headers or authentication schemes at all.
The Bearer authentication scheme is designed exactly for your use case:
Authorization: Bearer e1d9753f-a508-46cc-a428-1787595d63e4
Basic authentication must be as follows:
Authorization: Basic base64EncodedUsernameAndPassword
where base64EncodedUsernameAndPassword is equal to the output of:
base_64_encode(username + ':' + raw_password)
Do not use Basic if the trailing text value is not the above exact algorithm.
If you just want to put whatever value you want after the scheme name, use the Bearer scheme - that is what it was invented for.
Warning
While you can use a simple GUID/UUID as your token, this isn't really a secure token. Consider using a JWT instead. JWTs can be digitally signed and assigned a TTL so that only the server setting it can a) create it and validate its authenticity and b) ensure it is not used longer than is allowed. While this may be true of your data stored based on the GUID, the JWT approach does not require server state - so it scales far better - and accomplishes the same thing.
The general "Authentication with Token" approach is very good but you shouldn't try to make Basic Authentication work in different way than it is supposed to (after all it is a defined standard). You should rather use your own header for authentication purposes. You can find a very good description of such scenario here:
Making your ASP.NET Web API’s secure