I will start off by saying I have followed a guide of how to make a secure API using FastAPI (https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/).
What happens is that you will have two api which one is post and get
POST is where you pass the
curl -X POST "http://127.0.0.1:8000/token" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=&username=hello&password=world&scope=&client_id=&client_secret="
GET is an api that requires the access_token Bearer to be able to access the API etc http://127.0.0.1:8000/getUser
Now I am pretty confused on how safe you can run the application because what makes me confused is that I would need to make a POST request with my username and password to the API which will return me access_token and I believe with that access_token I later on access the next api which is http://127.0.0.1:8000/getUser? Is this the correct way or am I out of scope?
Because what makes me unsafe is that if I now lets say "hardcode" my username and password into a python script and someone manages to reverese engineer the script/exe/whatever (Maybe even see through network what is sending as params/data)- they will be able to access my token in that case. So what would be the suggestion here?
It's a pretty broad question. A good place to start is probably the OAuth2 RFC 6749.
Some of the foundational understanding that need to get right as a first step is:
A precondition of OAuth2.0 is TLS. Assuming you're using TLS 1.2 or 1.3 with appropriate cipher suites, we can safely assume network sniffing is not a possibility
If you're using OAuth2.0 on behalf of a human user, you'd use "Authorization Code" or "Password Credentials" grant types where the user would enter the username password manually
If you're using OAuth2.0 on behalf of the client itself (NOT a human user), you'd use "Client Credentials" grant type
All these grant types have different flows. Since you've mentioned about hard coding, I'm assuming you're referring to the use case mentioned in point no. 3. Hard coding secrets is NEVER an option. The most secured way to handle this is, storing the secrets in a Vault. A less secured option is to store the secret in a separate file in encrypted form.
I'll recommend you to read the following answers as well:
https://stackoverflow.com/a/59433000/1235935
https://stackoverflow.com/a/54011649/1235935
https://stackoverflow.com/a/54258744/1235935
https://stackoverflow.com/a/59464645/1235935
Related
When I have for example a post method - login, I get back the signed JSON web token. I watched some tutorials on youtube and there, when they check if the user is authorized, they send the JWT in the authorization header like:
Bearer -token-
My question is: why they do that, when the same thing is working if we send only the token in the authorization header, without the "Bearer" in front of the token?
Because it's in the relevant standards documents. The general scheme is that you first state the type of token ("Bearer" in this case) and then the token itself. There are other authentication schemes too and they use different type keywords (like "Basic" or "Digest"). If you control the web server and parse the headers yourself then, sure, you can use whatever syntax you like. You can even invent your own header, nobody's stopping you. But having it comply to a unified standard makes it a little easier down the road when you need to integrate with other systems. :)
I am using this npm to authenticate through Google to the system.
I have Jira atlassian, that uses Google to authenticate.
Question
Is it possible to use the token that I received from Google, and use it to authenticate into Jira's API of that user to gather information from Jira such as grabbing all tasks assigned to me, and such?
Or do I have to make OAuth specify for Jira ?
Of course you can do this, that is the point of delegated authentication.
Google will send you an authentication token when user will logs in.
I never work with google. I always used keyclock (3 part OAuth provider). But that is a beauty of a spec it should work everywhere the same.
It will be save in the cookie.
It will have o form of JWT.
You have to attache is token to the request that you send to the jira API.
You can try this with curl first
curl -i http://dev.myapp.com/api/jira ... \
-H "Authorization: Bearer Ym9zY236Ym9zY28=afsfdsf...."
You can find the token when looking at the network traffic in your browser.
Let me know how it went. And if I can help further. I have a pretty good understanding of the OpenIDconnect and OAuth 2.0 standards.
i am totally confused about the usage of OAuth and i am not sure how to use oauth for my szenario. At the moment i use a "pure" JWT approach which looks like that:
Client (JavaScript Application) send login and password to my Rest-Endpoint (Server (Java)).
Server validate user informationen, read / generate some user roles and wrap it in a JWT Token (with a secret)
Server send JWT Token back to client
Client will perform additional Rest-Calls with Authorizationen Header
Server validates Token with private secret and grand access based on roles/user
Now i think about the usage of OAuth but i am confused how to use it to realize the szenario.
I registered an application at "auth0".
I use a JS library to redirect to the login process of auth0, login via auth0 account and consume the id_token and access_token
= i can send the id_token (JWT with RSA256) to my rest api, validate it with the public certificate and can extract some user information
but:
a) i have read that i should not use the id_token to access my api. Instead i should use the access_token (which is not in JWT format and will not give me any information about the user) and use the access_token to query for the user information? That whould be the case for every request?!
b) i don't see the point where the user roles come into play. When i have some operations (rest endpoints) which are only allowed for "admins" or "customers". I don't see any possibility to define them.
You see i am a little bit confused, i hope somebody can clarify all the things.
Thanks a lot
Chris
a) Both tokens you use should be in JWT format and you should use access_token for authenticated queries. The access_token not necessarily contains information about the user, so on server side you usually can decide only that the token is emitted by the token service and is valid. If all these checks are passed, you should accept it as an authenticated user.
b) User roles can be placed into the access_token's payload section as an additive claim (e.g. role=admin,datawriter or role=customer,listreader) like many other things.
I hope it helps.
a) Sounds like you are getting an opaque access_token back and not a JWT. You'll need to create an API in Auth0 (similar to the application/client you already created). Then you pass that identifier in the audience parameter when you authenticate. Then you should get a JWT back, and that will have a sub parameter which is the Auth0 ID of the user, which can help you identify who the user is. I believe you could also use Auth0 rules if you need to put more identification info into the token. See here for a full explanation of the opaque vs. JWT access token: https://auth0.com/docs/tokens/access-token
b) Roles are tricky. I believe Auth0 would suggest that you create scopes on your API, and then request the scopes needed during login. Auth0 Rules would then be used as a sort of "glue", to adjust scopes that were requested but not permitted for the authenticated user. They also have an Authorization Extension you can use to help facilitate some of this. Another option could be storing role info in the user metadata, and using rules to put that info into the token. Finally, the option we chose was to not use Auth0 to define our roles. We let Auth0 authenticate, and once authenticated we check access in our system for the authorization side of things. Lots of options.
I have poured over the OAuth2 docs and seen how the Facebook Javascript SDK uses Implicit Grant.
I am building a ReactJs application, which communicates with a PHP-Symfony API.
What I want to do is offer the "Login with Facebook" option on the frontend.
What I need on my PHP server is the Facebook user id and email and other data of the user so I can initially create a user record for them in my DB and then on returning visit, use the auth token to get that info again on the server and use it to match it to existing records and log the user in.
We have done this previously using the Authorization Code Grant method to redirect the frontend to our server, then to facebook and then back to us with the auth code. We then use that on the server with our Secret Key to get the Access Token and get the user info directly from Facebook to our server and then authenticate the user.
The redirection is a bit of a pain for a single page application.
Facebook's Javascript SDK handles a lot of that automatically, but uses Implicit Grant, returning an Access Token directly to the frontend.
What I want to know is, can I just send that Access Token to my server to do the same type of authentication that I did before? Or is that a massive security hole that I am opening up?
Comparing the two, the Auth Code from the Authorization Code Grant flow also goes via the frontend, but very quickly, not directly to JavaScript and is much shorter lived. So it feels much more secure.
If intercepted in time and with matching state, it could be used to authenticate someone on our server, but not access someone's Facebook data directly.
Reusing the frontend Access Token from the Implicit Grant flow feels like it is open to messing with, but I can't put my finger on the exact scenario that would make it more vulnerable to attack. The token would potentially give people access to not only authenticating on our server but also to accessing people's Facebook info.
So this is ultimately a question of best practice and security.
We think that we should be able to implement our own popout window that does the Authorization Code Grant style flow and retrieves our server cookie which can then be used by the page that spawned it, but it is going to be tricky and most of the work seems to be done for the Implicit Grant method, if it is safe to use as we intend to use it.
Best Practices AND According to the RFC 6749
However, this convenience should be weighed against the security
implications of using implicit grants, such as those described in
Sections 10.3 and 10.16, especially when the authorization code
grant type is available.
Is there any way to validate my OAuth token for the github API? By 'token' I mean the one I get after the user has logged in to my website. I store it on the client computer using cookies, but just checking if there is a token is not enough: I need to actually check if the token is valid or not. Currently this requires me to make a request for information and then catching the errors. However, this is really damaging my rates and also my load speed as the github API is sloooow... I am using Node.js, express and the octonode library.
I tried looking at the github API docs, but they are minimal. Maybe this is to do with OAuth.
Check headers to see what OAuth scopes you have, and what the API action accepts:
curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/users/codertocat -I
HTTP/1.1 200 OK
X-OAuth-Scopes: repo, user
X-Accepted-OAuth-Scopes: user
From the Github API docs on authorizations:
OAuth applications can use a special API method for checking OAuth token validity without running afoul of normal rate limits for failed login attempts.
Authentication works differently with this particular endpoint. You must use Basic Authentication when accessing it, where the username is the OAuth application client_id and the password is its client_secret. Invalid tokens will return 404 NOT FOUND.
You can do this with curl:
curl -u client_id:client_secret https://api.github.com/applications/:client_id/tokens/:token
Or, if using fetch, use Curl to Fetch.
This is compiled from the helpful comments on the OP's question.
curl -H "Authorization: <TOKEN>" https://api.github.com/
Or
curl https://api.github.com/ -u <USERNAME>:<TOKEN>