Check the "grant_type" parameter - oauth-2.0

I am using OAuth 2.0 for authorization according to this documentation :(https://developers.vendhq.com/documentation/oauth.html#oauth) and having this error:
"error": "invalid_request", "error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the \"grant_type\" parameter."
Request
Method : POST
Content-Type: application/x-www-form-urlencoded
URL : https://{domain_prefix}.vendhq.com/api/1.0/token
Parameters :
code = {code}
client_id = {app_id}
client_secret = {app_secret}
grant_type = authorization_code
redirect_uri = {redirect_uri}

As per the RFC6749, section 4.1.3, the encoded body of a POST request should look like code={code}&client_id={app_id}&client_secret={app_secret}&grant_type=authorization_code&redirect_uri={redirect_uri}.
Example:
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&client_id=CLIENT_ID_1234&client_secret=CLIENT_SECRET
Do not forget to encode the redirect Uri: http://foo.bar/ => http%3A%2F%2Ffoo.bar%2F
Concerning the authentication error, it may be because the authorization server do not support client secret in post request (or your client is not allowed to use it).
Then try to add the Authorization header with basic authentication scheme.
The value of this header is Basic {ENCODED_AUTHENTICATION} with {ENCODED_AUTHENTICATION} =base64(client_id + ':' + client_secret)
With this header, the client_id and client_secret in the post request have to be removed. Your request parameters become code={code}&grant_type=authorization_code&redirect_uri={redirect_uri}.

You will need to check the URL to which you are attempting to send your POST to. The service that you are attempting to contact does not exist or is currently unavailable.

Related

Is there a way to add aud element in the OAuth 2 with grant type = Auth code with PKCE in postman

I've added Audience parameter from advanced options but I don't see a parameter added in the postman console.
Below is a sample request & highlighted in bold is the parameter that needs to be added on the authorize request in postman.
https://{ehr_authorize_url}?
response_type=code&
client_id=app-client-id&
redirect_uri=https://{app_redirect_url} &
launch=123&
scope=openid+fhiruser&
state=abc&
aud=https://{fhir_base_url}&
code_challenge={XXXXXXXXX}&
code_challenge_method=S256
Unfortunately, Postman doesn't support adding 'aud' in the authorization request. The value you provide in the 'Audience' input of the advanced options will be used as 'audience' parameter in the request body of the token generation endpoint.
However, there's a workaround where you can pass the 'aud' in the 'Auth URL' as a query string parameter like this:
You can do the same for 'Access Token URL' to get a token with 'aud' claim

Implicit grant type: Invalid grant_type parameter value WSO2

I try generate a access token in my application on WSO2 using implicit grant type, following the request:
POST /token HTTP/1.1
Host: localhost:8243
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: d6ef6038-9860-bdc6-3867-70af98b37cc6
grant_type=code&response_type=implicit&client_id=CLIENT_ID&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fplayground%2Foauth2client&scope=default
And the request return this error:
{
"error_description": "Invalid grant_type parameter value",
"error": "invalid_request"
}
This is my grant types settings:
Grant Types
Why this error happen, although the settings include the implicit grant type?
I think you are mixing up few things. If you want to use the Implicit grant, you don't use the /token endpoint - you get everything from the authorization endpoint. The request could look like this:
/auth?response_type=token&client_id=...&redirect_uri=...
and after a successful authentication, the client gets an access token right away as part of the redirect URL.
If you have a code and you want to exchange it for an access token and a refresh token, you are using the Authorization code grant. Then the correct grant_type value is authorization_code and you must specify the code in the code URL parameter. So the error message you are getting is correct.
Finally, the token endpoint has no response_type parameter. It's a parameter of the authrization endpoint and the correct value for the implicit flow is token, because you want an access token to be returned.

Cannot get OAuth 1.0 Token in OpenBankProject request due to missing oauth_callback

I'm trying to use OpenBankProject to get Token, but in Postman I cannot do this due to Status 400 Bad Request and the following parameters are missing : oauth_callback.
From doc I get info that it should be:
Method POST
Authorization: Add params to header
Content-Type: application/x-www-form-urlencoded
Signature Method: HMAC-SHA256
Generated Consumer Key and Consumer Secret
And I tried to add Value oauth_callback="___" to Key Authorization and it returned same error as mentioned above.
Any idea to add oauth_callback to this request?
Best regards

Paw not finding access_token from OAuth proxy

I have a use-case where I need to spoof a white-listed Redirect URL locally when performing OAuth 2 authentication.
I'm running a very basic web-server coupled with a hosts file entry for the domain I'm spoofing. I'm able to correctly negotiate my tokens and return them to Paw, but Paw isn't picking up my access_token or refresh_token, it simply displays the raw response:
Here's my server code (with placeholders for sensitive data):
var http = require('http'),
request = require('request');
var PORT = 6109;
var server = http.createServer(function(req, res) {
var code = req.url.split('?')[1].split('=')[2];
request({
url: 'https://<access token URL>/oauth2/token?code=' + code,
method: 'POST',
form: {
'client_id': <client_id>,
'client_secret': <client_secret>,
'grant_type': 'authorization_code',
'redirect_uri': <spoofed redirect URL>
}
}, function(err, response, data) {
data = JSON.parse(data);
res.writeHead(200, {'Content-Type': 'application/json'});
res.write(JSON.stringify(data.result));
// I also tried this with the same end-result
// res.writeHead(200);
// res.write('access_token=' + data.result.access_token + '&token_type=' + data.result.token_type + '&refresh_token=' + data.result.refresh_token);
res.end();
});
});
server.listen(PORT, function() {
console.log('Server listening on port %d', PORT);
});
What am I missing? Why isn't Paw finding my tokens?
Here's my configuration for reference:
Some other noteworthy points:
The OAuth provider is non-standard and flubs quite a few things from the spec (my proxy exists in part to patch up the non-standard bits)
The domain for the Redirect URL is real, but the URL does not resolve (this is a part of the reason for the local hosts entry)
I'm not showing this part of the flow, but I am correctly completing the authorization step prior to being given the code value
I think you're probably confused between the Authorization URL and Access Token URL. When you're in Authorization Code grant type for OAuth 2, you're expected to have a user confirmation step in a web page (the Authorization URL).
Which makes me guess that instead, you're expecting instead to use the Password Grant or Client Credentials? Otherwise, if you want to use Authorization URL, you'll need to specify a webpage at the Authorization URL.
Note: I've tried your Node.js script in Paw using the two last grants I mentioned (Password Grant & Client Credentials), and it works nicely.
Update: Following the comments below, I understand more what you are doing. The Authorization Request should (if successful) return a 302 redirect response to the Redirect URL page, and append a code URL query param to it. It seems like you're returning a JSON response with the code instead, so Paw isn't catching it.
According to the OAuth 2.0 spec (RFC 6749), section *4.1.2. Authorization Response*, if granted, the code should be passed as a URL query param (i.e. a ?key=value param in the URL) to the Redirect URL when doing the redirection.
If the resource owner grants the access request, the authorization
server issues an authorization code and delivers it to the client by
adding the following parameters to the query component of the
redirection URI using the "application/x-www-form-urlencoded" format
Quoting the example from the spec, here's how the response of the Authorization Request should look like if it's a success (code is granted):
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz
I saw that the Redirect URL contains "my Spoofed Uri".
When we need to use authorization code flow, we provide the authorization code and redirect Uri.
When the URI you are providing does not match the URI saved for the client in Identity server, you will not be able to get the token as the URI does not match with the client authorization code.
For example : Consider client identity in the Identity server be:
Auth Code: "xyx"
Redirect Uri: "www.mylocalhost.com\xyz"
And in your example the combination you are providing is:
Auth Code: "xyx"
Redirect Uri: "<my spoofed uri>"
As these 2 wont match there will be no token received.
I believe if you use the correct URI that is registered with the client in the Identity server, you will be able to receive the token.

Authenticating to an API with a token

I'm working with the Zendesk API, an HTTPS-only, JSON API and authentication is required to update a resource, and the API supplies an API token to use when authenticating as different users. When updating a resource, I issue a PUT request over SSL, assign the appropriate JSON content to the request body, and specify the Content-Type request header as application/json.
Next, the API instructs its users to authenticate as the end-user by either using the user's email and password (which I can't do for several reasons) or to use the user's email address along with the API token. The following is my attempt to authorize to the API with the Authorization header:
#id = params[:id]
#comment_body = params[:comment]
uri = URI.parse "https://{subdomain}.zendesk.com/api/v2/requests/#{#id}.json"
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Put.new(uri.request_uri)
req.body = '{"request": {"comment":{"value":' + "\"#{#comment_body}\"" + '}}}'
req['Content-Type'] = 'application/json'
#The following two lines do not work!
credentials = Base64::encode64("{user_email}/token:{api_token}")
request.headers['Authorization'] = "Basic #{credentials}"
response = http.request(req)
The API specifies that the format for authentication using the API token is {user_email}/token:{api_token}. I encoded that format with Base64::encode64 and passed it to the Authorization Header preceded with Basic, but the response is a 401 Unauthorized. However, replacing those two lines with req.basic_auth {user_email}, {user_password} works fine.
So my question is, how can I authenticate as a different user using the email and the given API token as authentication instead of supplying the user's email and password to req.basic_auth?
The googling I've done on the topic has revealed very little; apparently it's a lot more common to use the normal {username}:{password} format when dealing with the Authorization header than an API token.
Thanks in advance!!
Update: Weirdly, trying to authenticate as the end-user with req['Authorization'] = "Basic #{credentials}" does not return a 401 Unauthorized Error or a WWW-Authenticate header while trying to authorize as request.headers['Authorize'] = "Basic #{credentials}" does.
Finally figured it out after much head-banging and nearly throwing my laptop out the window. Suddenly, the answer seems incredibly obvious.
When using Net::HTTP, its basic_auth method can also accept tokens depending on the API, and the Zendesk API specifies that the format for using the API token is {email}/token:{token}. Basic authentication uses the format {username}:{password}, where the two fields are separated by a colon, meaning in Zendesk's case I can place {email}/token as the first argument and {token} as the second argument (instead of the username as the first argument and the password as the second argument), so the following code is correct:
req.basic_auth "{email}/token", "{api_token}"
I hope anyone who found this useful could leave a comment. Nice to know I spared someone from this frustration.

Resources