2012-11-16 16 views
19

मैं इंट्रानेट वेब ऐप के लिए नैन्सीएफएक्स का उपयोग करना चाहता हूं। सभी दस्तावेज और मंच केवल फॉर्म और मूल प्रमाणीकरण का जिक्र करते हैं। विंडोज प्रमाणीकरण के साथ कोई भी सफलतापूर्वक नैन्सी का उपयोग करता है?नैन्सीएफएक्स और विंडोज प्रमाणीकरण

नैन्सी नामक कुछ भी है। प्रमाणीकरण। बेकार लेकिन मैं नहीं देख सकता कि यह क्या करता है (ऐसा लगता है कि यह एपिस में उपयोग के लिए है)।

उत्तर

8

मैं हाल ही में एक आंतरिक परियोजना में इस प्रयोग किया जाता है - मैं वास्तव में नहीं है ऐसा लगता है कि, और यह की मेजबानी 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; 
       }; 
     } 
    } 
} 

यह सब सुरक्षा जांच को नजरअंदाज यदि यह स्थानीय (परीक्षण के लिए) से आ रहा है, जो शायद एक बुरा विचार है, लेकिन यह फ़ायरवॉल चीज के पीछे है इसलिए यह इसके लिए कोई मुद्दा नहीं है।

आप इसे शब्दशः उपयोग करें, लेकिन सही दिशा :)

2

तुम मुझे खत्म Nancy.Authentication.Ntlm मदद करने के लिए कोशिश कर सकते में आप इंगित कर सकता का सुझाव नहीं होगा। यह निश्चित रूप से पूर्व-अल्फा है। मुझे नहीं पता कि नैन्सी आंतरिक के सीमित ज्ञान पर आधारित कई चीजों को कैसे लागू किया जाए।

वर्तमान में कोड क्लाइंट को चुनौती देता है, उत्तर को सत्यापित करता है। लेकिन मैं इस ऑपरेशन की सफलता के बारे में ग्राहक को सूचित करने में असफल रहा।

लेकिन मैं अभी भी कड़ी मेहनत कर रहा हूं। वास्तव में मुश्किल है।

और मैं आपकी टिप्पणियों की सराहना करता हूं और यदि कोई हो तो अनुरोध खींचता हूं।

17

मुझे बुनियादी इंट्रानेट एप्लिकेशन के लिए नैन्सी के साथ विंडोज प्रमाणीकरण की आवश्यकता थी। मैंने @ स्टेवेन रॉबिन्स का एक प्रारंभिक बिंदु के रूप में जवाब दिया, लेकिन उन चीजों को हटा दिया जिनकी हमें आवश्यकता नहीं थी और फिर 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 => 
      { 
       //... 
      }; 
    } 

}

+0

धन्यवाद, यह मेरे लिए एक बहुत मदद की। आप इसे कैसे संशोधित कर सकते हैं ताकि यह मॉड्यूल स्तर की बजाय प्रति अनुरोध है? या आप बस प्रत्येक मार्ग के भीतर व्यक्तिगत दावों की जांच करेंगे? – mjbates7

+0

आप रूट हैंडलर के अंदर [this.RequiresAuthentication()] (https://stackoverflow.com/questions/12185257/nancyfx-authentication-per-route) जोड़ सकते हैं। –

+1

'ओविन' में स्वयं-होस्टिंग के मामले में वास्तव में सहायक नहीं है क्योंकि आप 'SystemFeb' से जुड़े होंगे, 'कोडफॉक्स' द्वारा दिए गए उत्तर मेरी आवश्यकताओं को पूरा करते हैं। – MaYaN

2

दिग्गजों की 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 

    } 
} 

IWindows प्रमाणीकरणप्रदाता:

using System.Security.Principal; 

namespace Your.Namespace 
{ 
    public interface IWindowsAuthenticationProvider 
    { 
     bool CanAuthenticate { get; } 
     IPrincipal GetPrincipal(); 
    } 
} 

WindowsAuthenticationProvider: के रूप में आप की जरूरत है IWindowsAuthenticationProvided हर मॉड्यूल

public DefaultModule(IWindowsAuthenticationProvider authenticationProvider) 
     { 
      this.RequiresWindowsAuthentication(authenticationProvider); 
      Get["/"] = _ => "Hello World"; 
     } 
16

नैन्सी का उपयोग के साथ WindowsAuthenticationthis thread से चर्चा की है में इंजेक्ट किया

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()); 
     } 
    } 
} 

यह लागू करने थोड़ा जटिल होता है। डेमियन हिकी ने 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; 
      }; 
     } 
    } 
} 

विशेष धन्यवाद डेमियन के लिए जाना!

  • Microsoft.Owin.Host.HttpListener
  • Microsoft.Owin.Hosting
  • Microsoft.Owin
  • Nancy
  • Nancy.Owin
  • :


    उदाहरण निम्नलिखित NuGet पैकेज की आवश्यकता है

  • Owin
+0

धन्यवाद दोस्त, मेरे दिन बचाया। – MaYaN

+0

एनटीएमएल के साथ भी ठीक काम करता है। – Thomas

संबंधित मुद्दे