Send bearer token in Swagger using Swagger-Net - swagger

I have recently made the transition from Swashbuckle to Swagger-Net. One problem that I'm having after making the change is that now I'm unable to call my APIs which require a token sent in the Authorization header. Below are how I had the code in SwaggerConfig.cs before in Swashbuckle and now Swagger-Net
Swashbuckle
//section for .EnableSwagger
c.ApiKey("apiKey")
.Description("API Key Authentication")
.Name("Authorization")
.In("header");
//section for .EnableSwaggerUI
c.EnableApiKeySupport("Authorization", "header");
Swagger-Net
//section for .EnableSwagger
c.ApiKey("Authorization", "header", "API Key Authentication");
For Swagger-Net I can't find any equivalent of the .EnableAPIKeySupport in the .EnableSwaggerUI portion. After accessing the /Swagger UI rendering and using Authorize passing my token it is not sending that token to the API. I can tell it's not being sent as it is not in the sample CURL given.

Yes on Swagger-Net the ApiKey is all you need
c.ApiKey("apiKey", "header", "API Key Authentication", typeof(KeyAuthAttribute));
Here is a working example:
http://turoapi.azurewebsites.net/swagger/ui/index#/Echo/Echo_Post
The "protected" actions will show a lock icon on the right
And when you execute them you can see that the curl has the right stuff
And the code behind is here:
https://github.com/heldersepu/TuroApi/blob/master/TuroApi/App_Start/SwaggerConfig.cs#L67

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

restsharp and Postman

I am attempting to get an OAuth2 access token from ZOHO using RestSharp code. The Postman simulation works correctly so I know there is something I'm missing in my code.
I always get an "invalid client id" result status. However in Postman, it works and returns a code when I click the "Get new access token". I have the same items as in the Postman authorization tab (client_id, client_secret, etc). In Postman, "Body" is set to "none", and there are no parameters or headers. The only difference between my code and postman, is that Postman requires the Callback URL. My code is trying to get the code using "self-client", which bypasses the callback URL.
I have tried several different alternatives to the request call including ParameterType.Body, and ParameterType.GetOrPost. Is GetOrPost the same as a form?
client = New RestClient(ZOHO_API_URL)
request = New RestRequest(TokenUrl, Method.POST)
request.AddHeader("content-type", "application/x-www-form-urlencoded") ' also tried: "application/json")
request.AddParameter("grant_type", "authorization_code",
ParameterType.GetOrPost)
request.AddParameter("client_id", Client_ID, ParameterType.GetOrPost)
request.AddParameter("client_secret", Client_Secret,
ParameterType.GetOrPost)
request.AddParameter("code", Grant_Token, ParameterType.GetOrPost)
response = client.Execute(request)
This is the translated Postman code for RestSharp:
var client = new RestClient("http://");
var request = new RestRequest(Method.POST);
request.AddHeader("Postman-Token", "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx");
request.AddHeader("cache-control", "no-cache");
IRestResponse response = client.Execute(request);
Any ideas on what I am doing wrong. I have tried to view the raw data coming across with Fiddler, but when I do that, Postman indicates a failure.
What code do I need to use to duplicate what Postman is doing?
How do I implement a callback URL if that is also required?
I quickly checked ZoHo REST API docs and it seems like you should use the Limited Input Device authentication flow.
From what I can understand from their help page, you indeed need to do a POST request, but parameters must be specified as query parameters:
https://accounts.zoho.com/oauth/v3/device/code?
client_id=1000.GMB0YULZHJK411248S8I5GZ4CHUEX0&
scope=AaaServer.profile.READ&
grant_type=device_request
You will also get better off with JSON set as a default for serialisation and content type just by using client.UseJson().
It maybe that Postman is following a redirect from your API endpoint as the functionality is different Postman verses RestSharp (possibly missing a trailing slash or similar).
Try adding
client.FollowRedirects = false;
to your RestSharp code and analyse the result.

Authentication session is not defined

I try to use Google Photos API to upload my images, base on the steps of the following link.
https://developers.google.com/photos/library/guides/upload-media
After following the Using OAuth 2.0 for Web Server Applications, I just get the Oauth2.0_token response(a JSON format with access_token, refresh_token...). However, after I put this token string with "Bearer " into request headers, the response is error 401, the error message is "code 16 Authentication session is not defined".
I cannot find any information to deal with it, thank for any help.
You probably have incorrect permissions. Make sure you request the token with the appropriate scope. For write-only access you need 'https://www.googleapis.com/auth/photoslibrary.appendonly'
src: https://developers.google.com/photos/library/guides/authentication-authorization#what-scopes
One reason this might be happening is that you initially authorized your user for read-only access. If you went through the authorization flow with a .readonly scope, your bearer token reflects that authorization (and the token is retained in your credentials file). If you change your scope but don't get a new auth token you will get this error when trying to upload. Simply redo the authorization flow with the new scope defined:
SCOPES = 'https://www.googleapis.com/auth/photoslibrary'
store = file.Storage('path_to_store')
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('google_credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
and your store will be populated with a new token that can be used for uploading.
You say you "just get the Oauth2.0_token response(a JSON format with access_token, refresh_token...)" and "put this token string with "Bearer " into request headers".
Unfortunately documentation on this isn't super clear in a lot of places. What you are supposed to provide after "Bearer" is the "access_token" field only, not the entire JSON string with all the token fields in it. For reference, this is a single string of random looking characters which probably starts with "ya29." and is pretty long - in my case it's 170 characters.

Can't deploy an app to Intune store via graph API - DeviceManagementApps.ReadWrite.All is an invalid scope?

We want to enable uploading apps to the Intune store via an API.
I saw this example on GitHub, and want to do something similar in JS, so I've tried using the same REST calls.
The problem is, I can't seem to make the https://graph.microsoft.com/beta/deviceAppManagement/mobileApps request properly - I always get 401. When making the same request via the Graph API Explorer it works fine.
I tried fixing my permissions, and I'm kinda stuck getting the correct token.
I did the following steps with an admin account, on both the "common" and our own tennant:
Called the admin consent - https://login.microsoftonline.com/nativeflow.onmicrosoft.com/adminconsent?client_id=<ID>&redirect_uri=<URI>
Got authorization from the user - https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=<ID>&response_type=code&redirect_uri=<URI>&response_mode=query&scope=DeviceManagementApps.ReadWrite.All
POST request to get the actual token -
https://login.microsoftonline.com/nativeflow.onmicrosoft.com/oauth2/v2.0/token
with the following body:
client_id: <ID>
scope: https://graph.microsoft.com/.default
client_secret: <secret>
grant_type: client_credentials
requested_token_use: on_behalf_of
code: <The code I got in step 2>
I tried changing the scope in step 3 to https://graph.microsoft.com/DeviceManagementApps.ReadWrite.All or simply to DeviceManagementApps.ReadWrite.All, but it says that it's not a valid scope.
I got a token in step 3, but when I try calling the actual API I receive this error:
{
ErrorCode:"Forbidden",
Message:{
_version: 3,
Message: "An error has occurred - Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 - Activity ID: 7b5c3841-976d-4509-b946-f7fdabd047d7 - Url: https://fef.msub02.manage.microsoft.com/StatelessAppMetadataFEService/deviceAppManagement/mobileApps?api-version=5018-05-02",
CustomApiErrorPhrase: "",
RetryAfter: null,
ErrorSourceService: "",
HttpHeaders: {"WWW-Authenticate":"Bearer realm=urn:intune:service,f0f3c450-59bf-4f0d-b1b2-0ef84ddfe3c7"}
},
Target:null,
Details:null,
InnerError:null,
InstanceAnnotations:[]
}
So yeah, I'm pretty much stuck. Anyone have any experience with it? I've tried making the calls in Postman, curl and via code, but nothing works.
Cheers :)
You have a couple issues going on:
You're using the Authorization Code Grant workflow but requesting Client Credentials.
The scope Device.ReadWrite.All is an application scope, it is only applicable to Client Credentials. It isn't a valid Delegated scope so it will return an error when you attempt to authenticate a user (aka delegate) using Device.ReadWrite.All.
Your body is using key:value but it should be using standard form encoding (key=value).
To get this working, you need to request a token without a user. This is done by skipping your 2nd step and moving directly to retrieving a token (body line-breaks are only for readability):
POST https://login.microsoftonline.com/nativeflow.onmicrosoft.com/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={id}
&client_secret={secret}
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&grant_type=client_credentials

Reddit API returns HTTP 403

Following the OAuth2 login flow described at https://github.com/reddit/reddit/wiki/OAuth2 I got to the point where POST-ing to https://www.reddit.com/api/v1/access_token returns something like this:
{'token_type': 'bearer', 'expires_in': 3600, 'scope': 'identity', 'access_token': '*****'}
Then I do
GET https://oauth.reddit.com/api/v1/me
With this header:
Authorization: bearer *****
The response is HTTP 403 Unauthorized. But why? It is clear that the access token has 'identity' scope. It is also documented that the /api/v1/me call requires this scope only. (See https://www.reddit.com/dev/api/oauth#GET_api_v1_me )
So why am I getting http 403?
I was experiencing the exact same issue as you described. In my case, I resolved the 403 by adding a faux user agent string in the request headers.
In my case, using HttpClient of C#, this proceeds like so:
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("User-Agent", "MockClient/0.1 by Me");
...
}
In my case this was because of a redirect.
Calling a non-oauth endpoint in my application (like https://www.reddit.com/r/learnpython/about.json) with the Authorization header would fail with code 403. But calling https://reddit.com/r/learnpython/about.json (without www) with the Authorization header succeeded. However both endpoints worked when I tried via Postman.
The reason for this is that reddit.com would redirect to www.reddit.com, which results in the Authorization header being dropped by Postman for the second request. In my application code, I was including the header with both requests, which explains the different behavior.
Solution: don't include the Authorization header when calling non-oauth endpoints.

Resources