I'm developing a web application to to fetch data from 'https://api.ebay.com/sell/analytics/v1/traffic_report'
I've a ebay developer account with
ClientId: MyClientId
ClientSecret: MyClientSecret
AppId: MyAppId
To achive this, I need a OAuth token
To get OAuth Token I do the following steps.
I browse the url bellow
https://signin.ebay.com/authorize?client_id=MyClientId&redirect_uri=RuName&response_type=code&state=analytics&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.analytics.readonly
It goes to
https://signin.ebay.com/ws/eBayISAPI.dll?VAppJanessa&reqinput=reqinput - auto generate
after sign in it redirects to 'Grant application access to MySiteDisplayName' page.
After I Agree it redirects to 'https://my_site.com/?state=analytics&code=code'
I've preapared a post request after collecting the code
I've executed the post request using POSTMAN like bellow
Post URL: 'https://api.ebay.com/identity/v1/oauth2/token'
Headers:
cache-control: no-cache
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Base64 value of 'MyClientId:MyClientSecret'
Body:
grant_type: authorization_code
redirect_uri: RuName
code: code returned from previous request
After post request I've got the result
{
"error": "invalid_grant",
"error_description": "the provided authorization grant code is invalid or was issued to another client"
}
Please tell me what is missing or wrong.
Looks like clientId and appId you are sending don't match each other, probably one is a production one and another being a developer one. Happened with me once.
If there are multiple apps being registered, each with its own appId under the same clientId, many times the client Secret Gets missed. Try checking the correct combination of all three.
Related
I am trying to create a Webex team using the following process. But not working. I had created JWT token and exchanged it for access token which I had passed in to the Authorization header in the API call. But I keep getting the error message that I mentioned below. And another fact is I can execute the same API with GET method which returns the number of teams I had.I had followed steps in the webex developer site. But I can't create the team.
Request URL:
https://api.ciscospark.com/v1/teams
Request Method:
POST
The following is the header that I passed to the API
Accept:
application/json
Content-Type:
application/json
Authorization:
Bearer eyJhbGciOiJSUzI1NiJ9.eyJtYWNoaW5lX3R5cGUiOiJhcHB1c2VyIiwiY2x1c3RlciI6IlBGODQiLCJwcml2YXRlIjoiZXlKamRIa2lPaUpLVjFRaUxDSmxibU1pT2lKQk1USTRRMEpETFVoVE1qVTJJaXdpWVd4bklqb2laR2x5SW4wLi4zRnp6Mkh4c2k0TnI4Z24yMk03cm1BLjhtUnRIYUhOWXBkQ2ZydUR1d0s0MnJNMlhZTEZvNHJKN0NTTkJSQ21kZFRnNTdzUzZ1cUVxcjZFakQ0Yk1JOUY5NFluOWx6VGFWcnRHVkpLOGo2djNzX1VBaTJ2Rnk5TDl3Z05SaUlOczB3NU5yTkxLLUx3TDNQdGhiMzJEYzF2TlhGZkRtakFmSjlOZG1QeEdMQVYxWU9EVnhnNE5MbnpHNDczY24zaTJlbWlfdVBzbk9LRTZHYjEwMVBkekdCSVVQaGRwMkY4bVZhd3hzN2pxbUdzVmEtdXJaYXhpN243emZyaXBjUE5HZjNhSURWb011LVkzaXN0ak03U2s1Qno4TXcwNFZueXpGYWt4LWw0WHlfdUVJalpDeXNsNU56TGNTWkVHc2hJRnJsVHZmdzZZU1J4elV0cXJ2Y3hrX09GT01ZeFRsSDVvSXVsSXdXRWpVQ2o5RTBWZVJMNHB2Z3BQYTRkOE1zNHR6Tmh3cmNpRV9Hd0Fob0tmOE9oMEVQZTM4MmdaOW5wNFJvOWRVSnBnRGszR3NhYWx4ZmJubFRmMmt6RWVjQlJCa0NnSEJXRjhUZXNpdWZWV2djWktZX0E1dXh0aTlMSTB0Umk5X3ZsNjJuTy1uMlh5dm1VZlQxUUxLNmthamJwU01renRUOHdLRkxxLVdTVk54TUJlMWRid094Ni1nN0c3bldLZ1J5ZEpEVEdrazMtRW9wbVRURnZhTEk2dkp6S3NGTzlGRUFJVld1ZFd2RWlWWjVXdVN3dS5yS3RJTzZ6aVpFVE1XV3ZhOEVZaElnIiwicmVmZXJlbmNlX2lkIjoiODlkNjdlZDUtOTU5My00YjBjLWI0MGEtMGFjOTE0OTZlZjZkIiwiaXNzIjoiaHR0cHM6XC9cL2lkYnJva2VyLndlYmV4LmNvbVwvaWRiIiwidG9rZW5fdHlwZSI6IkJlYXJlciIsImNsaWVudF9pZCI6IkMzMTE3NzIzYTBhNGM5ODVhOGJkNmRkYTc2Zjc3NjZjNTEzMjRiNmY0MWJmNGZlZjFjMmM4Mjc4NGExZjI5NzVjIiwidXNlcl90eXBlIjoibWFjaGluZSIsInRva2VuX2lkIjoiQWFaM3IwWkRabU1XWXhaVEF0T0dGbU15MDBOR05oTFdKa09EY3RZVFZrTmpjM056STBNamhoTkRkaU9XVXlNbU10TkdOaiIsInVzZXJfbW9kaWZ5X3RpbWVzdGFtcCI6IjIwMTkwNTI3MDQxNzQ4LjEwMloiLCJyZWFsbSI6IjM5ZWQ0NDRmLTU2NGUtNDFlNC05N2VkLWI4MWFmNzM0ZWVkMCIsImNpc191dWlkIjoiNjJkZWU2NjktNDE5OC00N2YzLWE2ODgtNzA4YWQxM2VjNDc3IiwiZXhwaXJ5X3RpbWUiOjE1NTg5NTIyNzA0NTB9.VNUms24YsiwNbU_KN0Y7v1osAilq1MMiIQn6DRnyNitJAgeTLuyrwiYM0JIaox-dQxQKBp897uAj9vksg0ik2-j2MddcRmx4gsVF787uw7VpCIiZNNME346__xddvmmttna7IErBTz84hqZsnvSlmKLpus4lQs_k9I8ZHTsuPJ9FRXPry6ZAmPjDk1uWGGWFXyOSgH-VkDj9hY9Fy_6r7MKIn0YV21dxIKaZVZ6DMo1NSJM68I-90Vv-QbQY3gBeH25ZXDNDDBJg6-woMF2QPk_N8zrL8G1WPRXxGAA_lqGr_qGq65CfOwuqGikpLsRtjhWU4sYDX3xrK918W08CFw
This is the parameter I passed to the API
name=hearingteam
This is the server response
{"message":"The request could not be understood by the server due to malformed syntax.","errors":[{"description":"The request could not be understood by the server due to malformed syntax."}],"trackingId":"ROUTER_5CEB64F0-FC8D-01BB-05C2-7AA62A6905C2"}
The API requires parameters to be passed in JSON format.
Eg : JSON.stringyfy({"name":"hearingteam"});
I am new to bot framework. I am trying to test bot which is deployed on the dev server.
I am following the following article:
https://blog.botframework.com/2017/06/19/load-testing-a-bot/
I have got a token from the OAuth URL. Now I am trying to send a message to my deployed bot endpoint. I am getting 200 status but somehow body response gives me to text/Html content asks me to sign into your account.
Bots endpoint: www.mydomain.azurwebsites.net/api/messages/v3
I have passed the authorization token in the header.
Authorization: bearer .
Can you please help me here?
Thanks
I'm working on building out some new functionality where we have an existing system. Our goal is to have different Angular SPA's communicate with APIs to present a new interface for our legacy app. A team has set up IdentityServer4 to use the legacy application for credentials verification.
The SPA, written in Angular 7, uses the implicit flow to authenticate. Response type is "token id_token" I've been able to get this flow to work insomuch as I can have an unauthenticated user come to the site, get kicked over to the IdentityServer authentication screens, log in with correct credentials, and then redirected back to the app. When I get the token back the claims object has a single value for aud, the client_id for the SPA, for example, spa-client. The access_token and id_token are both a JWT with RS256 as the signature method. Lastly, I've created an interceptor in the SPA to send the JWT (in actuality it just uses whatever value is sent back as the access_token) as the "Bearer" token on API requests.
I have now created a .NET Core 2.2 WebApi app to build out a service API to be consumed by the SPA. This app uses the IdentityServer4.AccessTokenValidation package to "protect" the API I've read the section in the IdentityServer4 docs. In my ConfigureServices method I've written the following to configure auth:
services
.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
if (string.IsNullOrWhiteSpace(serviceConfiguration.Authentication.Authority)) throw new ConfigurationException("", nameof(serviceConfiguration.Authentication.Authority), "An authority must be defined.");
if (string.IsNullOrWhiteSpace(serviceConfiguration.Authentication.ApiName)) throw new ConfigurationException("", nameof(serviceConfiguration.Authentication.ApiName), "An api name must be defined.");
options.Authority = serviceConfiguration.Authentication.Authority;
options.ApiName = serviceConfiguration.Authentication.ApiName;
if (!string.IsNullOrWhiteSpace(serviceConfiguration.Authentication.ApiSecret))
{
options.ApiSecret = serviceConfiguration.Authentication.ApiSecret;
}
options.RequireHttpsMetadata = false;
options.SupportedTokens = SupportedTokens.Both;
}
serviceConfiguration is a strongly type representation of my JSON appsettings.json
My understanding is that with options.SupportedTokens = SupportedTokens.Both will check the JWT and do introspection.
Now that all this is setup I've taken the simple example ValuesController that is created by the API template and added the [Authorize] attribute to it. Doing a simple GET request to this endpoint in Postman returns a 401 as I would expect.
Next I try logging into the SPA and going to a test page which will do the same but with the interceptor will have the bearer token, the access_token, or basically the JWT. I still get a 401 from the service.
Looking at the logs output by the service I don't see anything specific that is helpful:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 OPTIONS http://localhost:5001/api/values info:
Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 OPTIONS http://localhost:5001/api/values info:
Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
CORS policy execution successful. info: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
CORS policy execution successful. info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 61.1352ms 204 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 61.1272ms 204 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5001/api/values application/json info:
Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:5001/api/values application/json info:
Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
CORS policy execution successful. info: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
CORS policy execution successful. info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web)' info:
Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web)' info:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Route matched with {action = "Get", controller = "Values"}. Executing action
Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) info:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Route matched with {action = "Get", controller = "Values"}. Executing action
Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) info:
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed. info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed. info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. info:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. info:
Microsoft.AspNetCore.Mvc.ChallengeResult[1]
Executing ChallengeResult with authentication schemes (). info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
Executing ChallengeResult with authentication schemes (). info: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler[12]
AuthenticationScheme: Bearer was challenged. info: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler[12]
AuthenticationScheme: Bearer was challenged. info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) in 166.3038ms info:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web) in 162.8827ms info:
Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web)' info:
Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'Examples.TestApp.API.Web.Controllers.ValuesController.Get
(Examples.TestApp.API.Web)' info:
Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 459.6677ms 401 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 473.7648ms 401
Setting the logging to Trace didn't reveal anything else.
I did try going to Postman to see if I could do introspection on the token manually. I set up authorization to basic and set the Username to "test-api", the api id, and the password that I set in its client secret. In the body a set it to x-www-form-urlencoded with a key of "token" and the value the access_token. I get a 200 OK with claims along with "active: true". Seems like that should be good, right?
I don't own the IdentityServer implementation so I'm not quite sure what's going on at that end except for being able to log into the admin UI. I've logged into the admin UI for the identity server and double checked the settings for the client and the API. The client gets granted a "api" scope and the API gets the same scope "api". This is shown in the scope that is sent back in the introspection response as well as the token that I get from the client.
I've also tried setting the options.SupportedTokens = SupportedTokens.Reference and options.SupportedTokens = SupportedTokens.JWT. Neither had any change. :(
What am I doing wrong? Is this a configuration issue or me being an idiot (probably the latter).
EDIT: RE access_token and id_token
I was incorrect in the original question. The tokens are different (I need to look at more than just the header portion).
The audiences are weird. I've never paid attention to a possible difference here when decoding. My powers of perception must suck!
The access token has aud: "http:///resources"
The id_token has aud: "spa-client"
The access_token and id_token are both the same and are a JWT with RS256 as the signature method.
The access_token and id_token should not the same . For id_token the audclaim in token should be the name of the client , but in access token , your api name should be include in the aud , so that your api resource could validate that the access token is issued to make "my" api calls. You can use online tool like jwt.io to decode the claims in JWT tokens . Since you haven't post the configuration of client & IDS4 , you should check the response type,scope ... If using Fiddler to trace the request , it should like :
GET /connect/authorize/callback?client_id=js&redirect_uri=http%3A%2F%2Flocalhost%3A5003%2Fcallback.html&response_type=id_token%20token&scope=openid%20profile%20api1&state=xxxxxxxxxxxxxxx&nonce=xxxxxxxxxxxxxxxxxxx
In addition , from document : http://docs.identityserver.io/en/latest/topics/grant_types.html
For JavaScript-based applications, Implicit is not recommended anymore. Use Authorization Code with PKCE instead.
You can click here for code flow code sample .
Update :
the audience of access token should also include api name , apart from "http:///resources :
You could click here for code samples .
I am able to create folders and files in onedrive using Graph API. However first time I have to login to Microsoft account. Following is the link where I need to login:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_mode=form_post&response_type=code+id_token&scope={scope}&state={state}&nonce={nonce}&x-client-SKU={x-client-SKU}&x-client-ver={x-client-ver}
I wish to implement all these server sides. How could I get it done without login to Microsoft account? IF it is possible using some console code, then I think it could be done.
I performed following steps to create a console application to create folder in OneDrive:
1. Create Microsoft app:
Log into https://apps.dev.microsoft.com/
Create a new app
Enter some app name
Generate a new password an Application Secretes section
Add Platform in Platforms section.
Added a Web platform
Provide some redirect Url. This would be required, you may enter any localhost url also. I entered http://localhost:100/
Add following Delegate Permissions in Microsoft Graph Permissions section
Files.ReadWriteAll, Directory.ReadWriteAll, offline_access (offline access is very important permission, without this permission you will not be able to generate access token automatically)
Make sure LiveSDKSupport checkbox is checked in Advanced Options.
2. Generate CODE value for access token
Update following url with your app id (step 1.b) and redirect url (step 1.g).
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={client_id}&scope=User.Read User.ReadWrite User.ReadBasic.All Mail.Send Calendars.ReadWrite Mail.ReadWrite Files.ReadWrite offline_access&response_type=code&redirect_uri={redirect_url}
Paste url in browser address bar and make a get request(hit enter)
Login to your one drive account
Accept the user agreement
Code redirect url and get code query string from redirect url
3. Generate access token and refresh token from code value
Open Postman
Make a post request with following settings:
endpoint: https://login.microsoftonline.com/common/oauth2/v2.0/token
Headers > Content-Type: application/x-www-form-urlencoded
Body >
client_id: your client/app id from step 1
redirect_uri: your redirect url from step 1
client_secret: your client secret (app password generated in step 1)
code: code generated in step 2
grant_type: authorization_code
This will return a json with some values. Copy access_token and refresh_token from response. Access token can be used to create folder in one drive. However that will be valid from some time. To get new token we will required to generate new token using refresh token. Hence store refresh token in configuration file along with client id client secret and redirect url.
4. Generate access token from code:
This can be done from Postman as well as from code using simple post request with following parameters:
Endpoint: https://login.microsoftonline.com/common/oauth2/v2.0/token
Method: Post
Content Type : application/x-www-form-urlencoded
Data: "client_id={client_id}&redirect_uri={redirect_url}&client_secret={client_secret}&grant_type=refresh_token&refresh_token={refresh_token}"
This will return access token in response. Use that access token to create folder in one drive.
5. Create folder in OneDrive:
Make a post request to create folder:
Endpoint: https://graph.microsoft.com/v1.0/me/drive/root/children
Authorization: "Bearer {access_token generated in step 4}"
ContentType: application/json
Post Data: new { name = FolderName, folder = new { childCount = 0 } };
I'm having an issue with Twitter OAuth 1.0 during the request_token stage
If I set a oauth_callback of oob (or even omit the callback url) then it works fine, but then of course doesnt redirect the user to my web app afterwards.
N.B. I may be going about this the wrong way. I just want to specify a URL that the client browser should be directed to after having authorized the OAuth request on Twitter
As soon as I change the oauth_callback to my app's callback url, I get the error "Could not authenticate you"
I have setup the callback url in the app settings on twitter to exactly the same url as the one I am settings in the oauth_callback parameter of the request_token process which FYI is an HTTPS base url i.e. no path specified, https://www.example.com/
Any assistance would be appreciated
UPDATE
This request works (no callback url specified at all):
POST https://api.twitter.com/oauth/request_token HTTP/1.1
Authorization: OAuth oauth_consumer_key="----myconsumerkey----", oauth_nonce="r70s1926", oauth_signature="iFGmXEpDav0lVpge9Ls9ACGI6r0%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1503053275", oauth_version="1.0"
This request does not (callback url specified, same as twitter app setting):
POST https://api.twitter.com/oauth/request_token HTTP/1.1
Authorization: OAuth oauth_callback="https%3A%2F%2Fwww.example.com", oauth_consumer_key="----myconsumerkey----", oauth_nonce="707n8282", oauth_signature="0KWzeJwQ%2FNMfmdZ%2Bt0zNEU4g3Ag%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1503053306", oauth_version="1.0"
The request above returns:
{"errors":[{"code":32,"message":"Could not authenticate you."}]}
Because exclusion or a setting of oob works it sounds like an encoding problem within the signature generation.
Check that the oauth_callback url is double encoded within your signature base string which should look something like:
POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3Dhttps%253A%252F%252Fwww.example.com%26oauth_consumer_key%3Dmyconsumerkey%26oauth_nonce%3D707n8282%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1503057157%26oauth_version%3D1.0