Asp.Net Vnext Kestrel + Windows Authentication

ASP.NET vNext Kestrel + windows authentication

OK, I accept, that windows authentication is not available in Linux, but using the link in my question we can write a custom ActionFilterAttribute, which makes the NTLM authentication process:

public async override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = (ControllerBase)filterContext.Controller;
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (!(await IsAuthorized(filterContext.HttpContext, controller)))
{
filterContext.Result = new HttpStatusCodeResult(401);
}
}
else
{
//TODO check access rights
}
}

private async Task<bool> IsAuthorized(HttpContext context, ControllerBase controller)
{
if (!context.Request.Headers.ContainsKey("Authorization"))
{
context.Response.Headers.Add("WWW-Authenticate", "NTLM");
return false;
}

var header = context.Request.Headers["Authorization"][0].Substring(5);
var message = System.Text.Encoding.ASCII.GetString(
Convert.FromBase64String(header));
if (!message.StartsWith("NTLMSSP"))
{
return false;
}

//type 1 message received
if (message[8] == '\x01')
{
byte[] type2Message =
{
0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00,//Signature
0x02, 0x00, 0x00, 0x00, //Type 2 Indicator
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Security Buffer
0x01, 0x02, 0x81, 0x00, //Flags
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Challenge
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Context
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 //Target info
};
context.Response.Headers.Add("WWW-Authenticate", "NTLM "
+ Convert.ToBase64String(type2Message));
return false;
}
//type 3 message received
else if (message[8] == '\x03')
{
var userName = GetMessageString(message, 36);
var domainName = GetMessageString(message, 28);
var workstation = GetMessageString(message, 44);

var user = controller.DbContext.Users.FirstOrDefault(
u => u.WindowsAccount.ToLower() == userName.ToLower());
if (user != null)
{
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
context.User.AddIdentity(identity);

try
{
await controller.SignInManager.SignInAsync(user, false);
}
catch { }

return true;
}
}

return false;
}

private string GetMessageString(string message, int start, bool unicode = true)
{
var length = message[start + 1] * 256 + message[start];
var offset = message[start + 5] * 256 + message[start + 4];
if (unicode)
return message.Substring(offset, length).Replace("\0", "");
else
return message.Substring(offset, length);
}

Kestrel on AspNet vNext doesnt serve index page under /

You need to enable the DefaultFilesMiddleware using UseDefaultFiles() and place it before the call to UseStaticFiles():

app.UseDefaultFiles();
app.UseStaticFiles();

If you don't specify otherwise, the middleware uses the DefaultFilesOptions by default, which means this list of default file names will be used:

default.htm
default.html
index.htm
index.html

See MSDN

ASP.NET Core 2.0 HttpSys Windows Authentication fails with Authorize attribute (InvalidOperationException: No authenticationScheme was specified)

While writing up the post, I remembered coming across this subsection of the migration guide. It says to add

services.AddAuthentication(Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme);

to the ConfigureServices function.

I initially thought that this wouldn't apply to HttpSys, given the full name of the constant (especially the IISIntegration threw me off). Moreover, as of this writing, the HttpSys documentation completely fails to mention this.

For those targeting the full .NET Framework, this requires installing the Microsoft.AspNetCore.Authentication NuGet Package.

EDIT

As Tratcher points out, there is a similar constant from the HttpSys namespace you should rather use:

Microsoft.AspNetCore.Server.HttpSys.HttpSysDefaults.AuthenticationScheme

What is the best way to host an ASP.NET MVC6 Application

The "best" way to host ASP.NET MVC 6 is to choose the way that best matches your app's needs, of course! But that perhaps isn't so helpful as far as advice goes.

First, you need to consider the requirements of the application, such as:

  • Does it need to run cross-platform?
  • Does it need health management?
  • Does it need to use existing IIS modules?
  • Does it need to run in the context of another application?
  • Does it need to use Windows Authentication?
  • And no doubt many more requirements...

Here's a brief summary of the various hosting options and their pros/cons:

  • IIS is perhaps the most well-known host. It has been hardened for well over a decade. Many popular modules are available for it, including providing various security features. IIS has built-in support for Windows Authentication, logging, app warmup, health management, remote administration, and lots of other features.
  • IIS Express shares the same codebase as IIS, but can be run without admin privileges.
  • Kestrel is a cross-platform web server that is being written as part of ASP.NET 5 and is currently most suited for development work. It's very lightweight, which can be both good (nothing in the way!) and bad (not very many features).
  • Self-host is where you are master of your own domain. Nearly everything is up to you, including figuring out what should happen if there is an unrecoverable error. Self-hosting is a great option if you need to host a server within your app (e.g. a client app that uses a web server to host UI or services that the app directly uses).

There is certainly no one "best" way to host an ASP.NET MVC 6 app, but there are certainly many solutions catered to a variety of needs.

In my answer to ASP.NET vNext is host agnostic, what does it deeply mean? I covered a few other aspects of host agnosticism.



Related Topics



Leave a reply



Submit