11

मैं एक एमएसएसएलएल बैकएंड के साथ एमवीसी 3 का उपयोग कर इंट्रानेट एप्लिकेशन का निर्माण कर रहा हूं। मेरे पास प्रमाणीकरण और भूमिकाएं हैं (कस्टम भूमिका प्रदाता के माध्यम से) ठीक से काम कर रही हैं। जो मैं अब करने की कोशिश कर रहा हूं वह उपयोगकर्ता को ओवरराइड कर रहा है। उपयोगकर्ता की तरह वस्तुओं की अनुमति देने के लिए इडेंटिटी। इडेंटिटी.फर्स्टनाम। लेकिन मैं किसी भी कोड है कि मुझे पता चलेगा कि मैं एक कस्टम प्रदाता लेखन की कोशिश की है WindowsIdentityएमवीसी 3 विंडोज प्रमाणीकरण उपयोगकर्ता को ओवरराइड करें। छवि

में ऐसा नहीं कर पा सकते हैं:

public class CPrincipal : WindowsPrincipal 
{ 
    UserDAL userDAL = new UserDAL(); 
    public CPrincipal(WindowsIdentity identity) 
     : base(identity) 
    { 
     userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]); 
     this.identity = identity; 
    } 
    public UserInfo userInfo { get; private set; } 
    public WindowsIdentity identity { get; private set; } 
} 

और WindowsAuthentication अधिभावी कस्टम प्रिंसिपल को भरने के लिए।

void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e) 
    { 
     if (e.Identity != null && e.Identity.IsAuthenticated) 
     { 
      CPrincipal cPrincipal = new CPrincipal(e.Identity); 
      HttpContext.Current.User = cPrincipal; 
     } 
    } 

मेरे पास प्रमाणीकरण फ़ंक्शन में ब्रेकपॉइंट है और प्रिंसिपल पॉप्युलेट किया जा रहा है; हालांकि, जब मैं नियंत्रकों में ब्रेकपॉइंट डालता हूं, तो उपयोगकर्ता मेरे कस्टम प्रिंसिपल की जगह केवल सामान्य रोल प्रिंसिपल है। मैं क्या गलत कर रहा हूं?

संपादित करें:

मैं Global.asax में उपरोक्त कोड बाहर टिप्पणी की। मैं अधिरोहित है AuthorizeAttribute का उपयोग कर सी #: के लिए

public class CAuthorize : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     bool authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      return false; 
     } 


     IIdentity user = httpContext.User.Identity; 
     CPrincipal cPrincipal = new CPrincipal(user); 
     httpContext.User = cPrincipal; 

     return true; 
    } 

} 

और मेरे प्रिंसिपल समायोजित निम्नलिखित:

:

public class CPrincipal : IPrincipal 
{ 
    private UserDAL userDAL = new UserDAL(); 
    public CPrincipal(IIdentity identity) 
    { 
     userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]); 
     this.Identity = identity; 
    } 
    public UserInfo userInfo { get; private set; } 

    public IIdentity Identity { get; private set; } 

    public bool IsInRole(string role) 
    { 
     throw new NotImplementedException(); 
    } 
} 

अब मैं जब मैं में एक ब्रेकपाइंट शब्दों में कहें, घड़ी उपयोगकर्ता में निम्नलिखित से पता चलता

  • उपयोगकर्ता
    • [CSupport.Model.CPrincipal]
    • पहचान

पहचान सुलभ है, हालांकि, यह अभी भी WindowsIdentity सीपी निदेशक केवल घड़ी में पहुंच योग्य है और सीधे पहुंच योग्य नहीं है।

संपादित करें: इस में योगदान करने वाले सभी लोगों के लिए धन्यवाद। आपने विभिन्न भागों को कैसे काम किया है, इस बारे में मेरी समझ में काफी विस्तार किया है।

मुझे काम करने के दोनों तरीके मिल गए, इसलिए मैंने सोचा कि मैं साझा करूंगा।

विकल्प 1: Global.asax

में अधिकृत अनुरोध ओवरराइड यह एक मैं के साथ जा रहा हूँ है।

मैंने Application_AuthenticateRequest का उपयोग नहीं किया क्योंकि (HttpContext.Current.User is null even though Windows Authentication is on) उपयोगकर्ता को Windows प्रमाणीकरण प्रक्रिया में पॉप्युलेट नहीं किया गया है और इस प्रकार उपयोगकर्ता की जानकारी प्राप्त करने के लिए मैं कुछ भी नहीं कर सकता।

एप्लिकेशन_अधिकृत अनुरोध श्रृंखला में अगला है और विंडोज पहचान के बाद होता है।

protected void Application_AuthorizeRequest(object sender, EventArgs e) 
    { 
     if (User.Identity.IsAuthenticated && Roles.Enabled) 
     { 
      Context.User = new FBPrincipal(HttpContext.Current.User.Identity); 
     } 
    } 

यह इस तरह आप नए प्रधान बनाया गया था कि में अद्यतन जानकारी का उपयोग है प्रधान

public class CPrincipal : IPrincipal 
{ 
    private UserDAL userDAL = new UserDAL(); 
    public CPrincipal(IIdentity identity) 
    { 
     userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]); 
     this.Identity = identity; 
    } 
    public UserInfo userInfo { get; private set; } 

    public IIdentity Identity { get; private set; } 

    public bool IsInRole(string role) 
    { 
     return userDAL.IsUserInRole(userInfo.UserName, role); 
    } 
} 

की ओवरराइड है।

[Authorize(Roles = "super admin")] 
    public ActionResult Dashboard() 
    { 
     string firstname = (User as CPrincipal).userInfo.FirstName; // <-- 
     DashboardModel dModel = reportDAL.GetChartData(); 
     return View(dModel); 
    } 

विकल्प 2: AuthorizeAttribute

ओवरराइड यह है ओवरराइड प्रधान (यह वही ऊपर के रूप में है)

public class CPrincipal : IPrincipal 
{ 
    private UserDAL userDAL = new UserDAL(); 
    public CPrincipal(IIdentity identity) 
    { 
     userInfo = userDAL.GetUserProfile(identity.Name.Split('\\')[1]); 
     this.Identity = identity; 
    } 
    public UserInfo userInfo { get; private set; } 

    public IIdentity Identity { get; private set; } 

    public bool IsInRole(string role) 
    { 
     return userDAL.IsUserInRole(userInfo.UserName, role); 
    } 
} 

यहाँ अधिकृत की ओवरराइड गुण है

public class CAuthorize : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     bool authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      return false; 
     } 


     IIdentity user = httpContext.User.Identity; 
     CPrincipal cPrincipal = new CPrincipal(user); 
     httpContext.User = cPrincipal; 

     return true; 
    } 

} 

यह वह जगह है जहां आप नई सूचना के उपयोग और उपयोग करने के लिए प्राधिकृत एट्रिब्यूट बदलते हैं tion।

[CAuthorize(Roles = "super admin")] // <-- 
    public ActionResult Dashboard() 
    { 
     string firstname = (User as CPrincipal).userInfo.FirstName; // <-- 
     DashboardModel dModel = reportDAL.GetChartData(); 
     return View(dModel); 
    } 

विकल्प 1 वैश्विक स्तर पर कुछ भी संभालता है, विकल्प 2 व्यक्तिगत स्तर पर सब कुछ संभालता है।

+0

प्रतीक्षा करें ... वह ईवेंट हैंडलर क्या है? आप एएसपी.NET लॉगिन नियंत्रण का उपयोग करने की कोशिश नहीं कर रहे हैं? यह घटना कहां स्थित है और यह किस घटना में है? –

+0

मैं इंट्रानेट साइट पर विंडोज प्रमाणीकरण का उपयोग कर रहा हूं। यह घटना हैंडलर वैश्विक में है।Asax –

+0

global.asax में कोई ऑन प्रमाणीकरण हैंडलर नहीं है। शायद यही कारण है कि आपको समस्याएं आ रही हैं। –

उत्तर

6

इसे करने के बजाय, आपको global.asax में Application_AuthenticateRequest विधि को ओवरराइड करना चाहिए, फिर HttpContext.Current.User के बजाय Current.User का उपयोग करना चाहिए (सुनिश्चित नहीं है कि क्यों, लेकिन कोई अंतर है)।

फिर, अपने नियंत्रक में इस का उपयोग करने के लिए एक आसान तरीका एक विस्तार विधि बनाने के लिए है? इस तरह कुछ:

public static class IIdentityExtensions { 
    public static IMyIdentity MyIdentity(this IIdentity identity) { 
     return (IMyIdentity)identity; 
    } 
} 

तो आप बस User.Identity.IMyIdenty().FirstName कह सकते हैं। आप शायद इसे एक संपत्ति के रूप में भी कर सकते हैं।

protected void Application_AuthenticateRequest(Object sender, EventArgs e) 
{ 
    FormsAuthenticationTicket authTicket = FormsAuthentication 
     .Decrypt(authCookie.Value); 
    var identity = new MyIdentity(authTicket.Name, "Forms", 
     FormsAuthenticationHelper.RetrieveAuthUserData(authTicket.UserData)); 
    Context.User = new GenericPrincipal(identity, 
     DependencyResolver.Current.GetService<ISecurityHandler>() 
      .GetRoles(identity.Name).ToArray()); 
} 

अब, DependencyResolver सामान और कस्टम प्रमाणन टिकट सामान अनदेखी, यह बहुत बुनियादी है और मेरे लिए सही ढंग से काम करता है:

यहाँ कोड मैं का उपयोग करें।

फिर, मेरे एप्लिकेशन में, अपने कस्टम पहचान से जानकारी की आवश्यकता है जब मैं कर रहा हूँ, मैं सिर्फ ((IMyIdentity)User.Identity).FirstName या जो कुछ भी मैं जरूरत के साथ डाली। यह रॉकेट विज्ञान नहीं है, और यह काम करता है।

+0

मैंने केवल प्रमाणीकरण की आवश्यकता की कोशिश की और प्राप्त किया: HttpContext.Current.User शून्य है और वर्तमान मौजूद नहीं है। 'शून्य Application_AuthenticateRequest (वस्तु प्रेषक, EventArgs ई) संरक्षित { अगर (HttpContext.Current.User.Identity! = अशक्त && HttpContext.Current.User.Identity.IsAuthenticated) { HttpContext.Current.User = नए CPrincipal (HttpContext .Current.User.Identity); } } ' –

+0

@TobyJones - मेरा संपादन देखें। AuthenticateRequest में प्रमाणीकरण करने के लिए यह आपका काम है। उपयोगकर्ता निश्चित रूप से शून्य है क्योंकि अभी तक कोई प्रमाणीकरण नहीं हुआ है। –

2

What am I doing wrong?

शायद [Authorize] विशेषता आपके परिवर्तनों को ओवरराइड कर रही है। तो बजाय में WindowsAuthentication_OnAuthenticate विधि में ऐसा करने का अपने Global.asax एक कस्टम Authorize विशेषता लिखते हैं, तो जैसे:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      return false; 
     } 


     var user = httpContext.User as WindowsIdentity; 
     CPrincipal cPrincipal = new CPrincipal(user); 
     httpContext.User = cPrincipal; 

     return true; 
    } 
} 

और उसके बाद अपने कस्टम का उपयोग डिफ़ॉल्ट एक के बजाय विशेषता:

[MyAuthorize] 
public ActionResult SomeAction() 
{ 
    // User.Identity will be your custom principal here 
} 

एएसपी में। नेट एमवीसी प्रमाणीकरण करने का मानक तरीका प्राधिकरण एक्शन फ़िल्टर के माध्यम से है, ग्लोबल.एक्सएक्स में घटनाओं के माध्यम से नहीं।

+0

प्राधिकृत विशेषता आपके संदर्भ को ओवरराइड नहीं करती है। –

+1

वैसे भी, एएसपी.नेट एमवीसी अनुप्रयोग में प्राधिकरण करने के लिए 'Global.asax' में ईवेंट का उपयोग करना बुरा व्यवहार है। आपको इसके बजाय कस्टम प्राधिकरण फ़िल्टर का उपयोग करना चाहिए। –

+1

वह अपने कोड में प्रमाणीकरण नहीं कर रहा है, वह सिर्फ अपने कस्टम प्रिंसिपल को लागू कर रहा है, जिसे अभी भी वैश्विक.एक्सएक्स में किया जाना चाहिए। –

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