Support Token Based Authentication in Swagger Documentation for Web API - c#

I am trying out swagger(SwashBuckle) for generating web api documentation. I have successfully generated the documentation using Web API documentation using swagger but I am not able to successfully send API requests, as we have token based authentication (custom header for authentication purpose) for few of the methods.
I tried to find out sample code/resources for the same but did not have much luck. Please let me know if someone has implemented/came across similar thing in their application.

I had the same problem some time ago, and asked in the blog http://bitoftech.net/2014/08/25/asp-net-web-api-documentation-using-swagger/ for a solution.
This was the answer that worked for me:
1.Add new file named “SwaggerExtensions”, then added new JS file named “onComplete.js”, you have to change the build action for this file to “Embedded Resource”.
2.Inside the file “onComplete.js” paste the following code:
$('#input_apiKey').change(function () {
var key = $('#input_apiKey')[0].value;
if (key && key.trim() != "") {
key = "Bearer " + key;
window.authorizations.add("key", new ApiKeyAuthorization("Authorization", key, "header"));
}
});
3.Open file “SwaggerConfig.cs” and inside the register method paste the code below:
SwaggerUiConfig.Customize(c =>
{
c.SupportHeaderParams = true;
c.InjectJavaScript(typeof(SwaggerConfig).Assembly, "AngularJSAuthentication.API.SwaggerExtensions.onComplete.js");
});
Note that you need to change the full assembly name to match your assembly name.
I believe thats it, once you run the UI you will notice that this file has been downloaded and it will set the authorization header correctly.

You need to set up API Key authorisation. The "Describing Security/Authorization Schemes" in the README at https://github.com/domaindrivendev/Swashbuckle has details on this but in short you need to do something like the following in your call to httpConfiguration.EnableSwagger()
c.ApiKey("apiKey")
.Description("API Key Authentication")
.Name("apiKey")
.In("header");
You then need to create a custom attribute derived from IDocumentFilter and apply it to the appropriate methods in your controllers. Lets say you call this ApiKeyFilter. You then need to register this with Swagger by adding the following in EnableSwagger()
c.OperationFilter<ApiKeyFilter>();
I'm not aware of sample code for an ApiKey attribute but I've used https://github.com/domaindrivendev/Swashbuckle/blob/master/Swashbuckle.Dummy.Core/SwaggerExtensions/AssignOAuth2SecurityRequirements.cs before for OAuth2, you should be able to adapt that.

Related

Microsoft.Azure.CognitiveServices.Language.SpellCheck NuGet not working with Bing Search API (unauthorized)

I'm using .net-core3.1 with Microsoft.Azure.CognitiveServices.Language.SpellCheck NuGet package. I've read through entire documentation around Bing/cognitive API but I still find it very confusing as there are multiple APIs doing the same thing.
I got the API key from Microsoft.BingSearch on portal.azure.com and I'm using the free subscription. My subscription should however be valid as I am already using their LUIS without problems. Azure links to https://learn.microsoft.com/en-us/bing/search-apis/bing-spell-check/quickstarts/rest/python for quick start but this does not work for me ("https://api.bing.microsoft.com/v7.0/SpellCheck" url gives me "NotFound" using the code below with my key).
code sample:
var x = new SpellCheckClient(new ApiKeyServiceClientCredentials("<API_KEY>"));
// endpoints I tried:
// x.Endpoint = "https://westeurope.api.bing.microsoft.com/v7.0/spellcheck";
// x.Endpoint = "https://cognitiveservices.azure.com/bing/v7.0";
// x.Endpoint = "https://api.bing.microsoft.com"; -- Not found
// x.Endpoint = "https://cognitiveservices.azure.com"; -- The requested name is valid, but no data of the requested type was found.
var y = await x.SpellCheckerWithHttpMessagesAsync("gona");
Using default endpoint gives me Unauthorized error code.
Anyone has any idea on how to use this API?
You are right, the endpoint seems to be wrong. As you can see in the documentation here, regarding this value:
Supported Cognitive Services endpoints (protocol and hostname, for
example: "https://westus.api.cognitive.microsoft.com",
"https://api.cognitive.microsoft.com").
So if you are using West Europe, it should be "https://westus.api.cognitive.microsoft.com"
You can also check your API key by directly testing the console here: https://westeurope.dev.cognitive.microsoft.com/docs/services/5f7d486e04d2430193e1ca8f760cd7ed/operations/57855119bca1df1c647bc358
Choose your resource region (the one selected during key creation on Azure portal)
Set your key value in "Ocp-Apim-Subscription-Key" field
Edit the "text" value in the query parameters
Run the request

ASP.NET WebAPI 2.2 SPA with social login and no MVC dependencies

I have been designing an application which is just a statically served client page designed to use bearer tokens to authenticate with the backing API, however recently I have been trying to add social login options to the back-end but have found it very difficult to find any examples not using MVC dependencies which I would like to avoid if possible.
This question was a great help to get started: ASP.NET Web API social authentication for Web and Mobile
However I have been struggling to get my project to work in the same manor, basically in the question I referenced he has configured a OAuthAuthorizationServerOptions.AuthorizeEndpointPath like this:
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/account/externallogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
//AllowInsecureHttp = false
};
Also in his backing api account controller he has the following action:
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
[AllowAnonymous]
[Route("ExternalLogin", Name = "ExternalLogin")]
public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
In this example I have not been able to figure out what the first parameter of the RouteAttribute (template) is actually referencing in the project, if anything, could someone maybe explain what it is doing in this context?
Now when running the sample project provided in the question sending a GET request to 'api/Account/ExternalLogin' the request will be handled on the action in his API account controller and I assume it has something to do with OverrideAuthentication but am getting a little out of my depth here and struggling to find strong examples of other usages of this attribute.
However I am fairly certain I have configured my WebAPI project correctly in the way he has described, however when sending a GET request to my OAuthAuthorizationServerOptions.AuthorizeEndpointPath it is not handled on my API account controller but instead by my implementation of OAuthAuthorizationServerProvider which returns a 'invalid_request' error.
Can anyone think of something that I might be overlooking which is causing my API account controller action to be ignored?
I also had a read through this article but it seems to have been written in an older version of WebAPI:
https://thompsonhomero.wordpress.com/2015/01/21/creating-a-clean-web-api-2-project-with-external-authentication-part-2/
Thanks for any help,
Alex.
Without actually seeing your GET requests that are being made, I can only assume that they do not meet expectations by the OAuth provider.
The provider first validates the request being made, THEN it hands control over to the endpoint's controller. Your code is most likely correct, it's just that the request is malformed.
I made a new project and was able to replicate the issue you describe by making a get request to the AuthorizeEndpointPath. Unfortunately, there's not much to go off of as to why, however if you decompile source, or manage to find the source, you can see what's going on here.
Decompiling the calling code of ApplicationOAuthProvider.ValidateClientRedirectUri I get:
await this.Options.Provider.ValidateClientRedirectUri(clientContext);
if (!clientContext.IsValidated)
{
LoggerExtensions.WriteVerbose(this._logger, "Unable to validate client information");
flag = await this.SendErrorRedirectAsync(clientContext, (BaseValidatingContext<OAuthAuthorizationServerOptions>) clientContext);
}
else
{
OAuthValidateAuthorizeRequestContext validatingContext = new OAuthValidateAuthorizeRequestContext(this.Context, this.Options, authorizeRequest, clientContext);
if (string.IsNullOrEmpty(authorizeRequest.ResponseType))
{
LoggerExtensions.WriteVerbose(this._logger, "Authorize endpoint request missing required response_type parameter");
validatingContext.SetError("invalid_request");
}
else if (!authorizeRequest.IsAuthorizationCodeGrantType && !authorizeRequest.IsImplicitGrantType)
{
LoggerExtensions.WriteVerbose(this._logger, "Authorize endpoint request contains unsupported response_type parameter");
validatingContext.SetError("unsupported_response_type");
}
else
await this.Options.Provider.ValidateAuthorizeRequest(validatingContext);
if (!validatingContext.IsValidated)
{
flag = await this.SendErrorRedirectAsync(clientContext, (BaseValidatingContext<OAuthAuthorizationServerOptions>) validatingContext);
}
else
{
this._clientContext = clientContext;
this._authorizeEndpointRequest = authorizeRequest;
OAuthAuthorizeEndpointContext authorizeEndpointContext = new OAuthAuthorizeEndpointContext(this.Context, this.Options, authorizeRequest);
await this.Options.Provider.AuthorizeEndpoint(authorizeEndpointContext);
flag = authorizeEndpointContext.IsRequestCompleted;
}
}
In this code, you can see that if the request has been validated and the request's specified ResponseType is not provided, it set's the context's error to "invalid_request".
I was able to get the request to go through to the ExternalLogin controller method successfully using the following request URI:
http://localhost:18086/api/Account/ExternalLogin?provider=none&client_id=self&redirect_uri=http://localhost:18086/&response_type=token`
P.S. As far as the route attribute on the controller, the "template" field specifies the string that will be used as a template to match incoming request URIs against to determine where the request should be routed.
P.P.S. Actual source code for the decompiled snippet can be found here

How to Update Account in StripeApi using C#?

I am trying to update Account in Stripe Api using Stripe.netlibrary ,using StripeAccountService and storing it in StripeAccountclass which i made by myself to store the result returned by API :
var accountService = new StripeAccountService("secretKey in string");
StripeRequestOptions option = new StripeRequestOptions();
option.StripeConnectAccountId = "AccountId to update";
StripeAccount x = accountService.Get(option);
x.Email = "Local#local.com";
//Then i do not know how to save changes back to api now.
But StripeAccountService class has no Update method define. How I can perform update on the Account.
I am using this library. Stripe api does have an update method too here.
Stripe.net does not support managed accounts: "Managed Accounts are a valuable service as well, but they are not available in Stripe.net yet." https://github.com/jaymedavis/stripe.net#stripe-connect
Stripe.net doesnot support Managed account but it can be done using following approach it is for update account.
I won't be able to give code but can provide the correct approach, it is tested.
https://api.stripe.com/v1/account
is the Url for updating stripe account.
Now you need to add two header and a body you can try WebRequest or httpclient class.
The reason i am unable to provide code because i did not do any research in adding multiple headers and a body.
so it would look something like this
Header
Property value
Authorization bearer "SecretKey"
Stripe-Account "acct_16uR8kKN01245679"
Body
Property value
email "test#test.com"
support_phone "555-867-5309"
You can see complete property list here. i picked few for demonstration purpose only.
Then save the response in any variable and it is done.

How do I get Google Calendar feed from user's access token?

Using OAuth I do get access token from Google. The sample that comes with Google and even this one:
http://code.google.com/p/google-api-dotnet-client/source/browse/Tasks.SimpleOAuth2/Program.cs?repo=samples
show how to use Tasks API. However, I want to use Calendar API. I want to get access to user's calendar. Can anybody tell me how do I do that?
Take a look at the samples:
Getting Started with the .NET Client Library
On the right side of the page linked above there is a screen shot showing the sample projects contained in the Google Data API solution. They proofed to be very helpful (I used them to start my own Google Calendar application).
I recommend keeping both your own solution and the sample solution open. This way you can switch between the examples and your own implementation.
I also recommend to use the NuGet packages:
Google.GData.AccessControl
Google.GData.Calendar
Google.GData.Client
Google.GData.Extensions
and more ...
This way you easily stay up to date.
Sample to get the users calendars:
public void LoadCalendars()
{
// Prepare service
CalendarService service = new CalendarService("Your app name");
service.setUserCredentials("username", "password");
CalendarQuery query = new CalendarQuery();
query.Uri = new Uri("https://www.google.com/calendar/feeds/default/allcalendars/full");
CalendarFeed calendarFeed = (CalendarFeed)service.Query(query);
Console.WriteLine("Your calendars:\n");
foreach(CalendarEntry entry in calendarFeed.Entries)
{
Console.WriteLine(entry.Title.Text + "\n");
}
}

Simple C# Evernote API OAuth example or guide?

Anybody know where I can find a simple example C# code example? Apparently really tough to find.
I'm just starting out, got my Developer key.
Initial (really noob question/presumption) - -Can (should/must) my solution be a web service client? No new libraries I need to install in .Net right?
Basically, as a test, I want to be able to securely present a single note from a private notebook in html similar to what the Everfort export in html looks like on a outside WebSite.
Many Thanks in Advance!
You should start by downloading our API ZIP from http://www.evernote.com/about/developer/api/. You'll find C# client sample code in /sample/csharp. This sample code demonstrates using the Evernote API from a desktop application that authenticates using username and password.
I am not sure if you ever got this working, but I was playing around with Evernote, OpenAuth and C# this morning and managed to get it all working. I have put together a blog post / library explaining the experience and outlining how to do it with MVC here - http://www.shaunmccarthy.com/evernote-oauth-csharp/ - it uses the AsyncOAuth library: https://github.com/neuecc/AsyncOAuth
I wrote a wrapper around AsyncOAuth that you might find useful here: https://github.com/shaunmccarthy/AsyncOAuth.Evernote.Simple
One prickly thing to be aware of - the Evernote Endpoints (/oauth and /OAuth.action) are case sensitive
// Download the library from https://github.com/shaunmccarthy/AsyncOAuth.Evernote.Simple
// Configure the Authorizer with the URL of the Evernote service,
// your key, and your secret.
var EvernoteAuthorizer = new EvernoteAuthorizer(
"https://sandbox.evernote.com",
"slyrp-1234", // Not my real id / secret :)
"7acafe123456badb123");
// First of all, get a request token from Evernote - this causes a
// webrequest from your server to Evernote.
// The callBackUrl is the URL you want the user to return to once
// they validate the app
var requestToken = EvernoteAuthorizer.GetRequestToken(callBackUrl);
// Persist this token, as we are going to redirect the user to
// Evernote to Authorize this app
Session["RequestToken"] = requestToken;
// Generate the Evernote URL that we will redirect the user to in
// order to
var callForwardUrl = EvernoteAuthorizer.BuildAuthorizeUrl(requestToken);
// Redirect the user (e.g. MVC)
return Redirect(callForwardUrl);
// ... Once the user authroizes the app, they get redirected to callBackUrl
// where we parse the request parameter oauth_validator and finally get
// our credentials
// null = they didn't authorize us
var credentials = EvernoteAuthorizer.ParseAccessToken(
Request.QueryString["oauth_verifier"],
Session["RequestToken"] as RequestToken);
// Example of how to use the credential with Evernote SDK
var noteStoreUrl = EvernoteCredentials.NotebookUrl;
var noteStoreTransport = new THttpClient(new Uri(noteStoreUrl));
var noteStoreProtocol = new TBinaryProtocol(noteStoreTransport);
var noteStore = new NoteStore.Client(noteStoreProtocol);
List<Notebook> notebooks = client.listNotebooks(EvernoteCredentials.AuthToken);
http://weblogs.asp.net/psteele/archive/2010/08/06/edamlibrary-evernote-library-for-c.aspx might help. As the author states it just bundles some and fixes some. Haven't tried it myself but thought I'd mention for a possibly easier way to get started. Possibly.
This might help too...found it using the Way Back Machine since the original blog site was offline.
https://www.evernote.com/pub/bluecockatoo/Evernote_API#b=bb2451c9-b5ff-49bb-9686-2144d984c6ba&n=c30bc4eb-cca4-4a36-ad44-1e255eeb26dd
The original blog post: http://web.archive.org/web/20090203134615/http://macrolinz.com/macrolinz/index.php/2008/12/
Scroll down and find the post from December 26 - "Get it while it's hot..."

Categories