MVC4 AntiForgery token cookie name is appended with random string - asp.net-mvc-4

I am encountering an issue with MVC4's
#Html.AntiForgeryToken()
html helper. On my development machine, when I run the project, upon inspecting the headers (using Fiddler) , the name of the token returned is
__RequestVerificationToken
But when deployed to an IIS version 7.5 (Windows 2008 R2), then token name looks like:
__RequestVerificationToken_L2V6b3JkZXI1
Where is this getting changed? Is it because my application is not deployed to the "root folder" of the IIS? E.g. my application is deployed to
"http://myserver/myapp" instead of "http://myserver"

I found the answer after looking at the source code:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.WebPages/Helpers/AntiForgeryConfig.cs
Yes, because my application was deployed to a path, the following code below appends the encoded equivalent of the path... Hope this finding will save you trouble.
// If the app path is provided, we're generating a cookie name rather than a field name, and the cookie names should
// be unique so that a development server cookie and an IIS cookie - both running on localhost - don't stomp on
// each other.
internal static string GetAntiForgeryCookieName(string appPath)
{
if (String.IsNullOrEmpty(appPath) || appPath == "/")
{
return AntiForgeryTokenFieldName;
}
else
{
return AntiForgeryTokenFieldName + "_" + HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(appPath));
}
}

Resolution to this problem is very easy by the use of AntiForgeryConfig class.See the reference below.
https://learn.microsoft.com/en-us/dotnet/api/system.web.helpers.antiforgeryconfig?view=aspnet-webpages-3.2
Namespace:System.Web.Helpers
You need to add below code under Application_Start() event of Global.asax file.
if (AntiForgeryConfig.CookieName.Contains("__RequestVerificationToken"))
{
AntiForgeryConfig.CookieName = "__RequestVerificationToken";
}

Related

PATCH request losing body on IIS but not on localhost

I have a web API, where I'm trying to support a PATCH request with a JSON Patch body to make changes to an object on the server.
I am using ASP Core with .Net 6, hosting using IIS on my web host.
This is the controller method:
public class BaseDataController<TEntity, TDetail, TNew> : ControllerBase
where TEntity : class, IIdentifiable
{
[HttpPatch("{id}")]
public virtual async Task<ActionResult<TDetail>> Patch(Guid id, [FromBody] JsonPatchDocument<TEntity> patch)
{
var item = await MainService.GetAsync(id);
if (item == null)
{
ControllerLogger.ItemNotFound();
return NotFound();
}
patch.ApplyTo(item, ModelState);
ValidationHelper.ValidatePatch(item, ModelState);
if (!ModelState.IsValid)
return BadRequest(ModelState);
await MainService.UpdateAsync(item);
return this.GuardResult(Mapper, item);
}
}
When I try to use this on my local machine, it works just fine. When I deploy to my web server, and make an identical request, I get a validation error and a 400 status code:
{"errors":{"":["A non-empty request body is required."],"patch":["The patch field is required."]}}
If I change HttpPatch to HttpPost and update the web request accordingly, it works fine.
Can anyone suggest what might be going wrong here? I'm assuming the server is baulking at the PATCH verb, but I can't work out how to make it happy. Googling is coming up with a load of WebDAV things, but the error codes don't match and ASP is clearly receiving the request (proven from the logs) when the description of the WebDAV issues suggests it wouldn't.
My working theory is that IIS is seeing the PATCH verb and doing something to the request body that ASP Core doesn't like, but I can't work out why or where to look to turn that sort of thing off.
When I try to use this on my local machine, it works just fine. When I
deploy to my web server, and make an identical request, I get a
validation error and a 400 status code: If I change HttpPatch to HttpPost and update the web request accordingly, it works fine
Well, your scenario is pretty obvious in context of IIS as you may know Http verb PATCH is not enabled as default accepted http verb on IIS Request Restrictions As you can see below:
Solution:
To resolve above incident, you outght to configure Request Restrictions on IIS and need to include ,PATCH so that it will allow http PATCH verb. On top of that, after that, please restart your application pool. You can follow below steps to implement that:
Step: 1
Select your app on IIS and then click on Handler Mappings Just as following
Step: 2
Select (Double click) ExtensionlessUrlHandler-Integrated-4.0
Step: 3
Click on Request Restrictions
Step: 4
Select VERB then include PATCH by comma seperated value as ,PATCH and click OK finally restart your application pool.
Note: For more details you can have a look on our official document here.

You must subclass the WebAuthenticatorCallbackActivity and create an IntentFilter for it which matches your callbackUrl

I am building a Xamarin Forms application with Google Authentication via OAuth2. There are quite a few examples of integrating Google Authentication into Xamarin forms but most of these posts appear outdated.
The most recent instruction from Microsoft is to use Xamarin Essentials based on this MSDN post. Microsoft's advice is to leverage a web backend to proxy the request to the third-party identity provider. In this case, I will be using an ASP.NET Core backend.
Within the Google cloud console, I have configured the redirect url of the OAuth web application to point to my deployed service instance in the cloud. This url is:
https://my-google-app.appspot.com/signin-google
Assuming my ASP.NET Core app is exposed at base url https://my-google-app.appspot.com.
In MobileAuthController, that provides the authentication URL for the application, copied from this Github repo, the callback scheme is supposed to be the URL registered in my app for deep linking as per my understanding of the flow so far:
someappname://abc
assuming the package name of my Android application is com.my-app-package-name. This all appears or sounds reasonable.
Somewhere in the mobile application, I am initiating the authentication request using the Xamarin Essentials package as follows:
var result = await WebAuthenticator.AuthenticateAsync(
new Uri("https://my-google-app.appspot.com/mobileauth/Google"),
new Uri("someappname://abc"));
In my Android project, I have an intent filter defined as follows:
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new []{Android.Content.Intent.ActionView},
Categories = new[] {Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable},
DataPath ="abc",
DataSchemes = new[]
{
"someappname" /* package id */
})
]
public class WebAuthenticationCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
{
}
}
So far, so good :). However, when I run the application, I get the error:
System.InvalidOperationException: 'You must subclass the
WebAuthenticatorCallbackActivity and create an IntentFilter for it
which matches your callbackUrl.
I have not been able to make sense of that error as Google will to redirect to my deployed ASP.NET instance which would then redirect to my app from my understanding.
UPDATE:
Correct my callback URL and problem persists.
This specific issue was being caused by a trailing slash in my redirect URL causing a mismatch between what I thought I was sending vs what the Xamarin app was constructing.
I ended up defining my redirect url as
someappname://callback/
The trailing slash ensures I can guarantee the same Uri being constructed on the Android intent which I then defined as follows:
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new []{Android.Content.Intent.ActionView},
Categories = new[] {Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable},
// need to ensure we have a backslash
DataPath = "/callback/",
DataScheme = "someappname")
]
public class WebAuthenticationCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
{
}
The c# Uri class will append a trailing slash at the end of your custom scheme if defined without a trailing slash and this would cause confusion as you do not expect this. The MSDN docs is not clear on this.

What is the correct way to host .well-known/openid-configuration?

I have a Blazor Server Project based on ASP.NET Core 5. I want to host my own openid-configuration discovery file. Since this file is served while running the OIDC workflow I want to verify what is the correct way to host this file. So far I have tried the following and only option 2 works.
using wwwroot/.well-known
This involves hosting the openid-configuration file statically in the wwwroot folder of my blazor server project.
After this if I run he project and try to access the file using localhost:44382/.well-known/openid-configuration, the file is not served.
Using Controllers
For this I just added a simple controller to my blazor project and specified .well-known/openid-configuration as a route for my anonymous controller HTTPGET action.
public class OidcConfigurationController : Controller
{
[HttpGet(".well-known/openid-configuration")]
public JsonResult OpenIdConfiguration()
{
return Json(new Storage.Storables.Security.OIDC.Configuration());
}
}
Now if I run the project with Option 2 and try to reach the localhost:44382/.well-known/openid-configuration the configuration JSON is served correctly.
Is option 2 the correct way to serve the OpenId-Configuration using ASP.NET Core and Blazor server project ? Will it cause any issues if I publish the server (for e.g. to Azure)
The reason why your first method is not working is that you don't serve a static file in a way the static file extensions assume you do. You missing a file ending, otherwise, the request isn't recognized as a file.
That said, you can write your own middleware. Give the file a proper ending like .json. If the resources /.well-known/openid-configuration/ is requested, you change the requested path to /.well-known/openid-configuration.json and let the static file extension handle the rest.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.Use(async (context, next) =>
{
if (context.Request.Path == "/.well-known/openid-configuration")
{
context.Request.Path = "/.well-known/openid-configuration.json";
}
await next();
});
app.UseStaticFiles();
...
}
For more information about writing a middleware have a look at the documentation https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write
However, you ran into the problem - I guess - because mostly this document is generated on the fly based on the configuration of your open id connect server like IdentityServer. So, maybe there is away around the static file?

Asp.Net Core signalR is not working if publishing inside virtual directory

I have developed an application in asp.net core and used signalR. When i publish it in root directory it works fine, but if i publish it inside virtual directory it doesn't work. My signalR hub is always pointing to the root directory.
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ... other middleware ...
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/chat");
});
}
And i have initialized it in client side like this,
chat.js
var connection = new signalR.HubConnection("/chat");
After publishing it inside virtual directory(/development/chatapp/source) it points like this,
http://localhost:100/chat?userId=1
But actually it has to point like this, so that it will work
http://localhost:100/development/chatapp/source/chat?userId=1
I have used asp.net core 2.0 and this signalR version(1.0.0-preview1-final).
Someone please suggest me to resolve this issue.
With the help of my friend i have found the root cause for this issue and i fixed it. Actually javascript doesn't know whether the application is hosted in root folder or sub folder(in virtual directory). It always points the root folder.
So when we are initializing it in js like this(new signalR.HubConnection("/chat")), it points the root directory as below,
http://localhost:100/chat?userId=1
Since javascript doesn't aware of IIS hosting, we need to tell the relative path from c#. So i get my application's base path as follows in controller,
ViewData["PathBase"] = Request.PathBase.ToString();
And if it has some value i just prepend it to '/chat', otherwise i just initialize it as '/chat'.
var connection = new signalR.HubConnection("/development/chatapp/source/chat");
This solves my problem :-)
Kailash P : With the help of my friend i have found the root ...
OK, thanks for your sharing.
I'm publish the SignalR Chat sample to IIS but NOT WORKS --X
SignalRChat :
 Tutorial: Get started with ASP.NET Core SignalR
 https://learn.microsoft.com/zh-tw/aspnet/core/tutorials/signalr?view=aspnetcore-2.2&tabs=visual-studio
*With Visual Studio debugging, the sample are works but NOT WORKS publish to IIS.
In page load, the send message button not enabled because there have some errors :
Failed to load resource: the server responded with a status of 500 (Internal Server Error)  chatHub/negotiate:1
[2019-11-18T06:40:26.977Z] Error: Failed to complete negotiation with the server: Error: Internal Server Error  Utils.ts:179
--
After add the vitural directory the SignalR Chat sample WORKS :
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
->
var connection = new signalR.HubConnectionBuilder().withUrl("/chat1/chatHub").build();
Don't know why there have no any official note about this problem (SignalR publishing).
[NET Core 2.2]
[Visual Studio 2019]

How to retrieve headers on AppHarbor hosted WCF-applications

Currently I have a WCF-based service deployed on AppHarbor. I'm having a issue with a GET operation defined like this:
[WebGet(UriTemplate = "feedcallback")]
Stream HandleMessageGet();
And implemented like this:
public Stream HandleMessageGet()
{
var value = WebOperationContext.Current.IncomingRequest.Headers["header.name"];
//Do stuff with header value
return ms;
}
Whenever I run this WCF application on localhost for debugging etc. it works fine; I can retrieve the header value. But whenever I deploy the project to AppHarbor, the get request doesn't function properly anymore because it can't retrieve the header from the WebOperationContext.
What could be causing this issue and how could this be solved?
In the end it seems to be an issue with the AppHarbor loadbalancer not forwarding headers with dots in them.
See: http://support.appharbor.com/discussions/problems/37218-header-not-being-forwarded