I want to use Bitbucket's Rest API with Bitbucket's two-factor authentication enabled, so I can administer my account using curl via the terminal. Previously, I made REST API calls without 2FA and now I want to make this transition.
With 2FA enabled, you need to use the OAuth 2.0 protocol to make API calls; rather than the standard REST API invocations you'll find on the Bitbucket site.
Now, I got as far as creating a so-called consumer, on the Bitbucket website. This generates a Key and a Secret.
The part where I got stuck is in the following. With this Key and Secret, you can obtain a so-called access token (which expires after an hour) via
https://bitbucket.org/site/oauth2/authorize?client_id={client_id}&response_type=code
, which you can do via a the curl command
$ curl -X POST -u "client_id:secret" \
https://bitbucket.org/site/oauth2/access_token \
-d grant_type=authorization_code -d code={code}.
I don't know how to obtain this access token; i.e., the step from invoking the curl command to having it in a Bash variable.
Once we've obtained our access token we can make API requests by including it in our curl command, according to the Bitbucket documentation. I presume, something like,
curl -u "client_id:secret" https://api.bitbucket.org/2.0/[API Request] --data-urlencode "access_token=$[Access_token]" --data "[api_request_data]=[Api_request_data]"
, where $[Access_token] is our Bash variable holding our unexpired access token.
I want to create two functions implemented in Bash: one to obtain an access token; and, one to refresh the access token. Or is there a more simple way?
Anyhow, a quick outline on how to make REST API calls with 2FA enabled, would be highly appreciated.
You can use a Bitbucket "app password". More info here.
Related
I'm trying to use the Tone Analyzer API in a Laravel application. No matter what I try, I always get the same response of {"code":401, "error": "Unauthorized"}. I suspect my issue is that I can't figure out how to pass in the API key, but the official documentation is no help whatsoever because it only contains instructions for using cURL in the command line. My code currently looks like this (though I have tried many many other iterations. If anyone needs me to I can post all the other unsuccessful attempts as well):
$response = Curl::to('https://gateway-wdc.watsonplatform.net/tone-analyzer/api/v3/tone?version=2017-09-21&sentences=false')
->withOption('HTTPHEADER', array(
'Content-Type: application/json',
'apikey: REDACTED'))
->withData(array('text' => $text))
->asJson()
->post();
I am running Laravel 5.8 and using Ixudra's cURL library. I would prefer if answers made use of this library too but honestly at this point I'm ready to give up and use vanilla PHP anyway so any answers are appreciated.
Ninja edit: I know the problem is not my account / API key, because I have tried to access the API through the command line and it worked just as expected. The issue only arises when trying to access it from Laravel.
IBM Watson Services uses HTTP Header Authentication in Basic format. Therefore, using curl in the terminal, you should pass the-u or --user flag in the format user:password, or you can also send the Authentication Http Header in pattern: Basic user:password.
By adjusting your code for this second form, you can do it as follows:
$response = Curl::to('https://gateway-wdc.watsonplatform.net/tone-analyzer/api/v3/tone?version=2017-09-21&sentences=false')
->withHeader('Content-Type: application/json')
->withHeader('Authorization: Basic apikey:YOUR_TOKEN_HERE')
->withData(array('text' => $text))
->asJson()
->post();
Replace YOUR_TOKEN_HERE by your Tone Analyzer API access token.
https://developer.mozilla.org/docs/Web/HTTP/Authentication
https://www.ibm.com/support/knowledgecenter/en/SSGMCP_5.3.0/com.ibm.cics.ts.internet.doc/topics/dfhtl2a.html
Hope this helps!
It's 401 status code which uses for unauthorized access, you need to login first before accessing the API.
I check the docs for this and here is the link, for login to the api before using it
tone-analyzer#authentication
With some service instances, you authenticate to the API by using IAM. You can pass either a bearer token in an Authorization header or an API key. Tokens support authenticated requests without embedding service credentials in every call. API keys use basic authentication.
I have looked at the two similar questions in StackoverFlow and on the web but I still don't understand what I should do.
I want to download a file that is located on OneDrive programmatically using a bash script (with curl).
So I've seen here that I can use the code flow to access Microsoft Graph. So I proceeded like that (I inspired myself from the Jay Lee answer):
1- I get the code with this URL
https://login.live.com/oauth20_authorize.srf?client_id=10c492f9-132a-4079-adae-382dad9d4339&scope=onedrive.readonly&response_type=code&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient
2- Then I swap authorization code for access token with this URL:
curl -X POST https://login.live.com/oauth20_token.srf -d "client_id=${client_id}&redirect_uri=${redirect_uri}&code=${auth_code}&grant_type=authorization_code" --header "Content-Type:application/x-www-form-urlencoded"
And I store the token and the expire time in a file
3- I made some process to handle the fact that I have to refresh the token (according to the expire time).
4- I use my token to download my file programmatically with Microsoft Graph
api_data=$(curl https://graph.microsoft.com/v1.0/me/drive/items/B8D9948257F95B84%21104/content -H "Authorization: Bearer $access_token")
echo -e "$api_data"
The problem- When I run the program, I get this:
How come?
You're authenticating against the wrong endpoint. The login.live.com endpoint cannot provide a valid token for Graph. You need to use the v2 Endpoint for this instead.
Check out Microsoft v2 Endpoint Primer for a walkthrough. Given that you're using curl, the pseudo code provided should give you everything you need.
What I Did
First I accept that I am lacking in spring security knowledge.
I am trying secure rest services for one of our product. I am using spring security OAuth2 JWT. I want to allow anonymous as well as registered users to access my resources.
Suppose I have one service "http://localhost:8282/melayer/articles" and when I run following command
(1). curl -X POST -vu melayer:12345 http://localhost:8282/melayer/oauth/token -H "Accept: application/json" -d "password=melayer&username=melayer&grant_type=password&scope=write&client_secret=12345&client_id=melayer"
I am able to receive access_token, refresh_token etc. Everything works fantastic, even I can access url http://localhost:8282/melayer/articles with received acces_token
(2). curl http://localhost:8282/melayer/articles -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NjA3NzY5NDIsInVzZXJfbmFtZSI6ImVjb2tyeXB0IiwianRpIjoiNWI5ZmE4NjYtMTBlNS00NDA2LTgxYmMtYjM3NWVmNGE0ZmQ1IiwiY2xpZW50X2lkIjoiZWNva3J5cHQiLCJzY29wZSI6WyJ3cml0ZSJdfQ.4jO9euBz4TSSNh7M3l2YBD1QPblE0ZyOfGm4VtyFMFY"
What I want to understand
I want to receive access_token anonymously i.e. I dont want to pass user name, password or client secret, I want to run curl command in following way
curl -X POST http://localhost:8282/melayer/oauth/token -H "Accept: application/json"
My one of the concern is, I want access_token with or without user credentials I am trying to achieve this from last week, Am I missing something ? is it possible ? what is correct way to do this ?
It is kind request to help me on this :)
If anyone want to see my code please refer Git repo https://github.com/aniruddhha/spring-security-oauth2-jwt
I think you Misunderstood the access token concept, access tokens are meant to be used on behalf of authenticated user.
OAuth2 supports different grants types (password, authorization_code, etc) , check the spec Oauth2 Spec
In order to authenticate used you can use any one of those grants or could create your own (eg: login with Google token ) but you must send some form of user credentials to identify the user and the client credentials to identify the client.
Access token cannot be used as some kind of ApiKey used to access public api
I connecting the google spreadsheet API. I have already granted permission to the user and retrieved the code. I would like to refresh the token with the refresh token, but cannot find the url. can anyone point me to the url needed? I cannot use the libraries since I am using an ETL tool and not a code to connect to the service.
Thank you
Nir
This worked for me:
curl https://www.googleapis.com/oauth2/v4/token \
-d client_id=$CLIENT_ID \
-d client_secret=$CLIENT_SECRET \
-d refresh_token=$REFRESH_TOKEN \
-d grant_type=refresh_token
For the first authorization code exchange, a refresh token is obtained in offline scenarios. In these cases, your application may obtain a new access token by sending a refresh token to the Google OAuth 2.0 Authorization server.
As discussed in the documentation, to obtain a new access token, your application sends an HTTPS POST request to https://www.googleapis.com/oauth2/v4/token.
We're using the username-password grant to obtain an access token from our auth server. We want to refresh the access token before it expires using the provided refresh token until the user logs out or closes the client app.
However I just cannot find any examples of how to issue this refresh token request..
To obtain the token we call something like:
curl -v --data "grant_type=password&username=user&password=pass&client_id=my_client" http://localhost:8080/oauth/token
So to refresh I'd expect the call to look like this:
curl -v --data "grant_type=refresh_token&access_token=THE_ACCESS_TOKEN&refresh_token=THE_REFRESH_TOKEN" http://localhost:8080/oauth/token
or maybe
curl -v -H "Authorization: Bearer THE_ACCESS_TOKEN" --data "grant_type=refresh_token&refresh_token=THE_REFRESH_TOKEN" http://localhost:8080/oauth/token
But it will just give me a 401..
Oh yeah, maybe I need to add the clientId? I cannot use the client secret, because there is none (see above request to obtain the token). Authentication is done using username and password after all..
I think we have the server configuration right, so I'll not post it here. If one of my example requests should work and you need to see the important config parts I'll add them.
Thanks!
So as I said, we don't use a client secret, because we cannot have that hanging around in the Javascript client app. And it's not needed anyway, when using the username-password grant. (See the way we request the access token).
Indeed I was close to the solution and finally figured it out:
curl -v --data "grant_type=refresh_token&client_id=THE_CLIENT_ID&refresh_token=THE_REFRESH_TOKEN" http://localhost:8080/oauth/token
so no need for the access token or the client secret.
Over all it feels safe enough.
We don't store any secret on the client app side.
The users always need a password to log in and can only see their resources.
We limit the validity of the refresh token to a realistic time like a workday or something so that even if it is compromised the window for an attacker is limited while still allowing the user to conveniently stay connected to the resource server throughout a long session.
For the password grant_type, a clientId and clientSecret are required. You were close with your third attempt, but you pass the Base64-encoded clientId and clientSecret instead of the Access Token in the Authorization header. This is the proper refresh token request:
curl -H "Authorization: Bearer [base64encode(clientId:clientSecret)]" "https://yourdomain.com/oauth/token?grant_type=refresh_token&refresh_token=[yourRefreshToken]"
For a good reference, check this out: http://techblog.hybris.com/2012/06/11/oauth2-resource-owner-password-flow/