我想將NancyFx用於Intranet Web應用程序。所有文檔和論壇僅提及表單和基本身份驗證。任何人都成功使用南希與Windows身份驗證?NancyFx和Windows身份驗證
還有一些叫做Nancy.Authentication.Stateless的東西,但我看不到它的作用(看起來像是在Apis中使用)。
我想將NancyFx用於Intranet Web應用程序。所有文檔和論壇僅提及表單和基本身份驗證。任何人都成功使用南希與Windows身份驗證?NancyFx和Windows身份驗證
還有一些叫做Nancy.Authentication.Stateless的東西,但我看不到它的作用(看起來像是在Apis中使用)。
我在一個內部項目最近使用過這一點 - 我真的不喜歡它,它關係到你的ASP.NET虛擬主機,但它做的工作:
namespace Blah.App.Security
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;
using Nancy;
public static class SecurityExtensions
{
public static string CurrentUser
{
get
{
return GetIdentity().Identity.Name;
}
}
public static bool HasRoles(params string[] roles)
{
if (HttpContext.Current != null && HttpContext.Current.Request.IsLocal)
{
return true;
}
var identity = GetIdentity();
return !roles.Any(role => !identity.IsInRole(role));
}
public static void RequiresWindowsAuthentication(this NancyModule module)
{
if (HttpContext.Current != null && HttpContext.Current.Request.IsLocal)
{
return;
}
module.Before.AddItemToEndOfPipeline(
new PipelineItem<Func<NancyContext, Response>>(
"RequiresWindowsAuthentication",
ctx =>
{
var identity = GetIdentity();
if (identity == null || !identity.Identity.IsAuthenticated)
{
return HttpStatusCode.Forbidden;
}
return null;
}));
}
public static void RequiresWindowsRoles(this NancyModule module, params string[] roles)
{
if (HttpContext.Current != null && HttpContext.Current.Request.IsLocal)
{
return;
}
module.RequiresWindowsAuthentication();
module.Before.AddItemToEndOfPipeline(new PipelineItem<Func<NancyContext, Response>>("RequiresWindowsRoles", GetCheckRolesFunction(roles)));
}
private static Func<NancyContext, Response> GetCheckRolesFunction(IEnumerable<string> roles)
{
return ctx =>
{
var identity = GetIdentity();
if (roles.Any(role => !identity.IsInRole(role)))
{
return HttpStatusCode.Forbidden;
}
return null;
};
}
private static IPrincipal GetIdentity()
{
if (System.Web.HttpContext.Current != null)
{
return System.Web.HttpContext.Current.User;
}
return new WindowsPrincipal(WindowsIdentity.GetCurrent());
}
public static Func<NancyContext, Response> RequireGroupForEdit(string group)
{
return ctx =>
{
if (ctx.Request.Method == "GET")
{
return null;
}
return HasRoles(group) ? null : (Response)HttpStatusCode.Forbidden;
};
}
}
}
它繞過所有安全檢查如果它來自本地(用於測試),這可能是一個壞主意,但它是防火牆之後的事情,所以這不是問題。
不會建議你使用它逐字,但可能你指出正確的方向:)
你可以試着幫我完成Nancy.Authentication.Ntlm。這絕對是pre-alpha。我不知道如何基於我對南希內部的有限知識來實現幾件事。
目前代碼挑戰客戶端,驗證答案。但我沒有通知客戶有關此操作的成功。
但我仍在努力工作。真的很難。
如果有的話,我會感謝您的意見和拉請求。
我需要Windows身份驗證與南希基本的Intranet應用程序。我以@Steven Robbins的答案作爲出發點,但剝離了我們不需要的東西,然後添加了NancyContext.CurrentUser
屬性的人口。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;
using Nancy;
using Nancy.Security;
namespace YourNamespace
{
/// <summary>
/// Extensions for Nancy that implement Windows Authentication.
/// </summary>
public static class WindowsAuthenticationExtensions
{
private class WindowsUserIdentity : IUserIdentity
{
private 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>
public static void RequiresWindowsAuthentication(this NancyModule module)
{
if (HttpContext.Current == null)
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 = GetPrincipal();
if (principal == null || !principal.Identity.IsAuthenticated)
{
return HttpStatusCode.Unauthorized;
}
context.CurrentUser = new WindowsUserIdentity(principal.Identity.Name);
return null;
}));
}
private static IPrincipal GetPrincipal()
{
if (HttpContext.Current != null)
{
return HttpContext.Current.User;
}
return new WindowsPrincipal(WindowsIdentity.GetCurrent());
}
#endregion
}
}
你使用這樣的:
public class YourModule : NancyModule
{
public YourModule()
{
this.RequiresWindowsAuthentication();
Get["/"] = parameters =>
{
//...
};
}
}
站在巨人的sholders,我以這種方式實現了它,以允許模擬來測試
認證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());
}
}
}
實現它是一個有點亂,因爲你需要的IWindowsAuthenticationProvided注入到每一個模塊
public DefaultModule(IWindowsAuthenticationProvider authenticationProvider)
{
this.RequiresWindowsAuthentication(authenticationProvider);
Get["/"] = _ => "Hello World";
}
使用南希WindowsAuthentication由this thread討論。 Damian Hickey提供了一個example of using Nancy, hosted by OWin with WindowsAuthentication。
我稍微修改了代碼(除去現在已經過時NancyOwinHost
):
namespace ConsoleApplication1
{
using System;
using System.Net;
using System.Security.Principal;
using Microsoft.Owin.Hosting;
using Nancy;
using Nancy.Owin;
using Owin;
internal static class Program
{
private static void Main(string[] args)
{
using (WebApp.Start<Startup>("http://localhost:9000"))
{
Console.WriteLine("Press any key to quit.");
Console.ReadKey();
}
}
}
internal sealed class Startup
{
public void Configuration(IAppBuilder app)
{
var listener = (HttpListener) app.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;
app.UseNancy();
}
}
public sealed class MyModule : NancyModule
{
public MyModule()
{
Get[""] = _ =>
{
var env = this.Context.GetOwinEnvironment();
var user = (IPrincipal) env["server.User"];
return "Hello " + user.Identity.Name;
};
}
}
}
特別感謝達米安!
該示例需要以下的NuGet包:
Microsoft.Owin.Host.HttpListener
Microsoft.Owin.Hosting
Microsoft.Owin
Nancy
Nancy.Owin
Owin
謝謝,這幫了我很多。你怎麼能修改這個,所以它是按請求而不是模塊級別的?或者你只是檢查每條路線內的個人索賠? – mjbates7
您可以在路由處理程序內添加[this.RequiresAuthentication()](https://stackoverflow.com/questions/12185257/nancyfx-authentication-per-route)。 –
在'OWIN'中自託管的情況並不真正有用,因爲您將被綁定到'System.Web','CodeFox'的答案符合我的要求。 – MaYaN