How to include X-XSRF-TOKEN header in Swagger UI? - asp.net-core

I have a .NET Core 3.1 Web API that I want to add XSRF protection to. So I now require an antiforgery token in an X-XSRF-TOKEN HTTP header on all of my endpoints as described here. JavaScript clients get a token by hitting the /antiforgerytoken endpoint, which sets an XSRF-TOKEN cookie containing the token. This all works fine, but as one would expect, the "Try it out!" feature in Swagger UI no longer works since the requests are missing the X-XSRF-TOKEN HTTP header. Is there a way to have SwaggerUI automatically call the /antiforgerytoken endpoint and include the token in the request being executed?

On Swagger UI, this can be supported by setting a requestInterceptor on the configuration which is a function that intercepts and modifies outgoing requests, including "Try it out" requests. See this comment in Swagger UI repo and the README on Swagger UI configuration.
However, Swashbuckle.AspNetCore.SwaggerUI does not yet support setting requestInterceptor in C# as of the latest stable release (5.6.3). There is this PR that added support for interceptors, and it has been merged but not yet released. So if you are using Swashbuckle.AspNetCore.SwaggerUI, your options for now is to wait for the next release, or build from source a local version before the next official release.

Related

OIDC challenge is the browser history for ASP.Net Core client

I use IdentityServer (aka Duende) ver. 6 and ASP.Net Core client as a BFF provider for the frontend with standard .Net Core Microsoft OIDC middleware .AddOpenIdConnect for the Authorization Code flow. Everything works nice except one small thing: browser history entry for the OIDC challenge which looks like https://myserver/connect/authorize/callback?client_id... It must be the same for any OIDC provider because this call must be done in a browser and cannot be replaced by AJAX.
It's just looking untidy with long URL and no page title in the history. If user hits back in a browser, it leads to the error because the challenge code is not valid anymore. The problem was precisely explained here and the solution history.replace was even implemented for the IdentityServer's JS client as a config parameter but I can't find anything similar for the .Net Core.
The solution for the browser back button is implemented on the IdentityServer side in their "QuickStart" sample and I also handle an error on the client but still this long untidy URL in the browser offends my eye. I would prefer replacing history instead.
The idea is to handle some event from the OIDC middleware and inject javascript with history.replace to the http context there. Maybe someone already has ready-to-go solution?

SignalR failing to authenticate via cookies

I have a couple of projects:
Chat - SignalR backend (ChatHub)
Web - MVC project that hosts clientside scripts, including those that make calls to the Chat project
I'm in the process of migrating from .NET Framework to .NET Core and am moving to SignalR for Core as part of this work. Cookie authentication is working correctly on the old version, but upon migrating to SignalR for Core, I appear to be having problems.
Cookie authentication is enabled in both projects. The Web project works fine and the Auth cookie is correctly recognised and used for authentication. The Chat project, however, is not correctly authenticated against the cookie, despite the cookie being included at least in the negotiate request:
When I make a call to the ChatHub, Context.User.Identity.Name is empty. The same call returns a populated name when run on the Web project. If I decorate the ChatHub with [Authorize], the call fails with a 401.
Here's a minimalistic repro project showing the issue.
I assume the problem is related to the Authentication I have configured, or perhaps the cross-domain nature of the call?
This documentation is pretty unhelpful, and only says the following:
In a browser-based app, cookie authentication allows your existing user credentials to automatically flow to SignalR connections. When using the browser client, no additional configuration is needed. If the user is logged in to your app, the SignalR connection automatically inherits this authentication.
This appears under some very basic configuration, which basically only calls app.UseAuthentication(). Alas, that configuration does not work for me.
How do I set Cookies authentication in SignalR for Core so it works across two projects?
The issue is that by default, the Data Protection system that ASP.NET Core uses to encrypt the auth ticket isolates apps from one another.
You need to configure data protection on each project you wish to share protected payloads to use the same key ring and app identifier:
services.AddDataProtection()
.SetApplicationName("<appName>")
// as well as the following calls if your projects are to be deployed on different machines
.PersistKeysToAzureBlobStorage(new Uri("<blobUriWithSasToken>"))
.ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());

Require request header for asp.net core webapi

I’m trying to get some direction as to where I could configure a set of webapi’s to require a set of request headers we’ll need for tracing purposes. We’re required to also generate a OpenAPI spec for these.
I’ve tried the approach here:
Web Api How to add a Header parameter for all API in Swagger
But this only generates the spec and doesn’t enforce the identified headers to be provided.
I did try the approach using the FromHeader attribute at the controller level which did cover both of my requirements but I need to be able to configure these headers using the appsettings configuration.
Is tapping into swagger and writing a custom middleware the only way to achieve what I’m looking for?
Thank you in advanced!

JWT authentication in SignalR Core from Angular

The post is almost duplicate as this question, but I am using new SignalRCore (1.0.0 alpha2).
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.0.0-alpha2-final" />
In my .NET Core 2.0 I use OpenIddict to authenticate user on server. On client I use angular2-jwt.
Now I need to know how can I connect on server with Authorization header access_token? I would assume that I should use custom request header when trying to connect on server.
Can this be done with new SignalR Core? I found this thread which mention that websockets does not support custom headers but I wonder if SignalR Core team did some magic to support this scenario.
This is not possible when you are using JavaScript client because some underlying APIs (like webSocket) don't allow setting headers. This is why you need to use queryString. Also, this thread on github may be useful.
If you are using the C# client setting headers is not possible at the moment but this is just a limitation of the API and should be fixed in the future.
EDIT
SignalR now has API that allows to pass JWT token to both C# and JavaScript client. It is also now possible to set headers when using C# client.

Returning a 401 Unauthorized from WCF Web API in an MVC 3 App

I'm using the WCF Web API (the latest version, which I think is 0.5, obtained from the VS2010 Ultimate integrated package dependency GUI).
I've got a simple API class exposed and in each method I'm making a call that performs authorization against the user. When the user is unauthorized, I throw an HttpResponseException with the 401/unauthorized code.
This works, and you can see that at some point in the Http Handler chain, the 401 was trapped. The problem is that the site in which the API resides contains ASP.NET Forms authentication... and so when it sees the 401, it tries to forward my client request to the logon page.
How do I disable this behavior for a particular sub-directory within my site? I've tried setting a location of "api" always allowing users... but I still throw a 401 which still causes ASP.NET to try and redirect me to the logon page.
I'm sure I'm just missing a simple configuration setting that tells forms auth to ignore requests for the /api/* directories, but I can't find any information on it.
I have described the problem and it's solution here (with Preview4): Basic Authentication with WCF Web API hosted in IIS / Getting a 404 - Disable Forms Authentication Redirection