Receiving errorCode 1004 with /token API endpoint - oauth

Do oauth token grants require a paid account? I attempted the following with both a free and trial account.
Sending /token POST as documented results in:
{
"errorCode": 1004,
"message": "You are not authorized to perform this action.",
"refId": "cd9hgzwmdduh"
}
I use these parameters:
grant_type: authorization_code
code: <acquired from step 1. in oauth flow>
hash: <see below>
I acquired the hash parameter with the following commandline operation:
export app_secret=<acquired from developer app profile.>
export code=<code acquired from step 1 in oauth flow.>
echo -n "$app_secret$code" | openssl dgst -sha256

These were my errors that I corrected before successfully achieving Get Access Token endpoint:
When creating the SHA256 hash I forgot to concatenate | in between the app_secret and the code. The correct sha256 hash to send should be:
echo -n "$app_secret|$code" | openssl dgst -sha256
Header should be:
Content-Type:application/x-www-form-urlencoded
Instead of sending as url query parameters, I should send as x-www-form-urlencoded parameters.
Here is a full text of the HTML protocol:
POST /2.0/token HTTP/1.1
Host: api.smartsheet.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&client_id=<client_id>&code=<code from step 1 of oauth flow>&hash=<see above>
```

Related

CURL API token request with grant_type=password

I need to generate an API token for my app. The docs from the external service shows me below info:
This request uses normal post webforms.
<password> must be md5 encoded.
Endpoint: api/token
Request: "grant_type: password
Password: <password>
Username: <USERNAME>
"
What I did was generate md5 encoded password in console:
> Digest::MD5.hexdigest("ZCW2OQo5yhfmTKutGjiCWQ==")
=> "53a89a22375a3665cfe4cb92ee17992b"
And put it into curl command like below:
curl -d "grant_type=password&password=53a89a22375a3665cfe4cb92ee17992b&username=my_user_name" -X POST https://enpoint/api/token
But instead of expected response I'm getting an error:
{"error":"invalid_grant"}
It seems that your password is already encoded in some way - it's a base64 encoding of a binary string.
Try to put your actual password instead of this already encoded version as argument of hexdigest.

When I add security Scheme as JWT in my OpenAPI definition, the "Try it out" feature in UI always returns 401: Unauthorized error

I have the following basic openAPI definition:
openapi: "3.0.0"
info:
description: >-
API which tests service
version: "1.0"
title: Test Service
servers:
- url: /
description: Localhost Server
security:
- bearerAuth: []
paths:
/test:
get:
operationId: app.test
responses:
200:
description: Test
content:
text/plain:
schema:
type: string
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
The Swagger UI shows "Authorize" option where I put the JWT token without "Bearer" keyword, and click on "Try it out". The response is:
{
"detail": "No authorization token provided",
"status": 401,
"title": "Unauthorized",
"type": "about:blank"
}
The curl command has the correct Authorization header, which also doesn't work if I execute it in a terminal.
However, if I remove the security tag from the OpenAPI definition, the "Try it out" as well as the curl command works.
Does anyone know what could be the problem? What is the correct curl command when using JWT security Scheme in OpenAPI?
I'm using JWT authentication in my app and this is my curl that works. I'm trying to figure out how to get OpenApi to generate the proper headers.
curl "${URL}/${ID}/${RESOURCE}" \
-H "Accept: application/json" \
-H "X-Requested-With: XMLHttpRequest" \
-H "Authorization: Bearer ${BEARER_TOKEN}" \
-H "Content-Type: application/json" | python -m json.tool

openAM token introspection always return active as false

I have deployed the OpenAM - AccessManagement (6.0.0.4) version. I am using Rest API's to get the access token using password flow. And trying to introspect the token.
1) get access token
$ curl \
--request POST \
--user "clientid:clientsecret" \
--data "grant_type=password&username=user&password=welcome&scope=openid" \
http://openam.mydomain.com:8080/openam/oauth2/access_token
2) get header token (to be used for authorization header while token
introspection in step 3)
$ curl \
--request POST \
--user "clientid:clientsecret" \
--data "grant_type=client_credentials&scope=openid" \
http://openam.mydomain.com:8080/openam/oauth2/access_token
3) introspect token
$ curl \
--request POST \
--header "Authorization: Basic ZGVtbzpjaGFuZ2VpdA==" \
--data "token=f9063e26-3a29-41ec-86de-1d0d68aa85e9"
"https://openam.mydomain.com:8080/openam/oauth2/introspect"
Token introspection is always returning as {"active" : false }. I guess I am missing some OpenAM configuration. any thoughts please?
UPDATE
As suggested by #BernhardThalmayr it is working when I gave token as query parameter. 3 issues here:
1)I need to give authorization header as encoded clientid:clientsecret.I can not use the bearer token generated in step 2 as authorization header.
With gluu as IDP, bearer token is accepted as auth header for token introspection.But with openAm it gives
{
"error_description": "Invalid authorization",
"error": "invalid_client"
}
I can see in docs for openam micro-services, for token validation bearer token being used as auth header. https://backstage.forgerock.com/docs/platform/6/mservices-guide/#sec-validate-am-sso-token. How to do it without microservice?
2) scope list is empty : I have added scopes in client configuration as openid, introspect, mail,cn,profile. still token introspection returns scopes array as empty
3) openam/oauth2/userinfo endpoint returns only {
"sub": "amadmin"
}
IMHO AM is not spec compliant as it requires the value of the token to be sent as query parameter [backstage.forgerock.com/docs/am/6/oauth2-guide/… in contrast to what is defined in [tools.ietf.org/html/rfc7662]. Have you tried to provide the token as documented in AM docs?

Azure AD OAuth token refresh gives error AADSTS50000

After successfully authenticating, I want to refresh my authorization token, so I issue the following request
curl -X POST \
https://login.microsoftonline.com/<my-tenant>/oauth2/v2.0/token \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-F grant_type=refresh_token \
-F refresh_token=<my-refresh-token> \
-F client_id=<my-client-id> \
-F client_secret=<my-client-secret>
However, instead of returning with a new token, I get the following response:
{
"error": "server_error",
"error_description": "AADSTS50000: There was an error issuing a token.\r\nTrace ID: bb72ee21-7df2-4949-8375-e6d97b621300\r\nCorrelation ID: 719ea759-622b-4d63-be17-56fd6c255195\r\nTimestamp: 2018-06-15 09:07:13Z",
"error_codes": [
50000
],
"timestamp": "2018-06-15 09:07:13Z",
"trace_id": "bb72ee21-7df2-4949-8375-e6d97b621300",
"correlation_id": "719ea759-622b-4d63-be17-56fd6c255195"
}
The tenant, client id and client secret are all the same as those used when obtaining the refresh token. Yet, something is apparently missing or incorrect - but what?
You are missing the mandatory scope parameter as described here.
You also need to provide a redirect_uri, although you just make a POST request.
And the redirect_uri must match the redirect_uri used in the original authorization call.
When refreshing an access token you have to provide a scope for which you would like to get the token. Also make sure that you understand you can only refresh the access_token, not the id_token. And access_token always has a purpose (scope).
Everything described in the documentation.

How to get the API token for Jenkins

I am trying to use the Jenkins REST API. In the instructions it says I need to have the API key. I have looked all over the configuration pages to find it. How do I get the API key for Jenkins?
Since Jenkins 2.129 the API token configuration has changed:
You can now have multiple tokens and name them. They can be revoked individually.
Log in to Jenkins.
Click you name (upper-right corner).
Click Configure (left-side menu).
Use "Add new Token" button to generate a new one then name it.
You must copy the token when you generate it as you cannot view the token afterwards.
Revoke old tokens when no longer needed.
Before Jenkins 2.129: Show the API token as follows:
Log in to Jenkins.
Click your name (upper-right corner).
Click Configure (left-side menu).
Click Show API Token.
The API token is revealed.
You can change the token by clicking the Change API Token button.
The non UI way to do this post Jenkins 2.129 is:
curl 'https://<jenkinsURL>/me/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken' \
--data 'newTokenName=foo' \
--user username:Password
which returns:
{
"status": "ok",
"data": {
"tokenName": "foo",
"tokenUuid": "<uuid>",
"tokenValue": "<redacted>"
}
}
Pre Jenkins 2.129
curl http://<username>:<password>#<jenkins-url>/me/configure
Tested in Jenkins 2.225
After making research for several hours I could find the answer:
The API token is used instead of the CSFR token. However, what happens if you want to make authentication from any other client (Postman, CLI, cURL, etc.)?
First you need to get a CSFR token and save the information in a cookie with --cookie-jar
Request
curl -s --cookie-jar /tmp/cookies -u username:password
http://localhost:8080/crumbIssuer/api/json
Response
{
"_class": "hudson.security.csrf.DefaultCrumbIssuer",
"crumb": "bc92944100d12780cfc251c9255f3f323a475562b4ee0d8b9cc6e4121f50a450",
"crumbRequestField": "Jenkins-Crumb" }
Then we can read the cookie with --cookie and generate the new token:
Request
curl -X POST -H
'Jenkins-Crumb:your_crumb_token_generated_above'
--cookie /tmp/cookies http://localhost:8080/me/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken?newTokenName=\your_token_name
-u username:password
Response
{
"status": "ok",
"data": {
"tokenName": "my android token",
"tokenUuid": "c510e26c-b2e8-4021-bf79-81d1e4c112af",
"tokenValue": "11a2a0c91913d1391d8e8cb155ca714581"
} }
How to a generate Jenkins API token
The following commands need curl and jq. Execute them in the same session.
# Change the following appropriately
JENKINS_URL="http://localhost:8080"
JENKINS_USER=admin
JENKINS_USER_PASS=admin
Get the Crumb
JENKINS_CRUMB=$(curl -u "$JENKINS_USER:$JENKINS_USER_PASS" -s --cookie-jar /tmp/cookies $JENKINS_URL'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
Get the access token
ACCESS_TOKEN=$(curl -u "$JENKINS_USER:$JENKINS_USER_PASS" -H $JENKINS_CRUMB -s \
--cookie /tmp/cookies $JENKINS_URL'/me/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken' \
--data 'newTokenName=GlobalToken' | jq -r '.data.tokenValue')
Consecutive API calls
Instead of the password, you need to use the token with the username along with the crumb that was generated.
curl -u $JENKINS_USER:$ACCESS_TOKEN \
-H $JENKINS_CRUMB \ ..........

Resources