Stojąc na sholders gigantów, jakie wprowadziły go w ten sposób, aby umożliwić uwierzytelnianie być wyśmiewany do testowania
using System;
using System.Collections.Generic;
using Nancy;
using Nancy.Security;
namespace Your.Namespace
{
/// <summary>
/// Extensions for Nancy that implement Windows Authentication.
/// </summary>
public static class WindowsAuthenticationExtensions
{
private class WindowsUserIdentity : IUserIdentity
{
private readonly string _userName;
public WindowsUserIdentity(string userName)
{
_userName = userName;
}
#region IUserIdentity
IEnumerable<string> IUserIdentity.Claims
{
get { throw new NotImplementedException(); }
}
string IUserIdentity.UserName
{
get { return _userName; }
}
#endregion
}
#region Methods
/// <summary>
/// Forces the NancyModule to require a user to be Windows authenticated. Non-authenticated
/// users will be sent HTTP 401 Unauthorized.
/// </summary>
/// <param name="module"></param>
/// <param name="authenticationProvider"></param>
public static void RequiresWindowsAuthentication(this NancyModule module, IWindowsAuthenticationProvider authenticationProvider)
{
if (!authenticationProvider.CanAuthenticate)
throw new InvalidOperationException("An HttpContext is required. Ensure that this application is running under IIS.");
module.Before.AddItemToEndOfPipeline(
new PipelineItem<Func<NancyContext, Response>>(
"RequiresWindowsAuthentication",
context =>
{
var principal = authenticationProvider.GetPrincipal();
if (principal == null || !principal.Identity.IsAuthenticated)
{
return HttpStatusCode.Unauthorized;
}
context.CurrentUser = new WindowsUserIdentity(principal.Identity.Name);
return null;
}));
}
#endregion
}
}
IWindowsAuthenticationProvider:
using System.Security.Principal;
namespace Your.Namespace
{
public interface IWindowsAuthenticationProvider
{
bool CanAuthenticate { get; }
IPrincipal GetPrincipal();
}
}
WindowsAuthenticationProvider:
using System.Security.Principal;
using System.Web;
namespace Your.Namespace
{
public class WindowsAuthenticationProvider : IWindowsAuthenticationProvider
{
public bool CanAuthenticate
{
get { return HttpContext.Current != null; }
}
public IPrincipal GetPrincipal()
{
if (HttpContext.Current != null)
{
return HttpContext.Current.User;
}
return new WindowsPrincipal(WindowsIdentity.GetCurrent());
}
}
}
go wykonawcza jest trochę brudny jak potrzebne są IWindowsAuthenticationProvided wtryskiwana do każdego modułu
public DefaultModule(IWindowsAuthenticationProvider authenticationProvider)
{
this.RequiresWindowsAuthentication(authenticationProvider);
Get["/"] = _ => "Hello World";
}
Dzięki, bardzo mi to pomogło. Jak możesz to zmienić, aby było to na jedno żądanie, a nie na poziomie modułu? A może po prostu sprawdzisz poszczególne roszczenia w ramach każdej trasy? – mjbates7
Możesz dodać [this.RequiresAuthentication()] (https://stackoverflow.com/questions/12185257/nancyfx-authentication-per-route) wewnątrz programu obsługi trasy. –
Niezbyt pomocne w przypadku samodzielnego hostowania w 'OWIN', ponieważ będziesz przywiązany do' System.Web' odpowiedź 'CodeFox' spełniła moje wymagania. – MaYaN