12

में विंडोज प्रमाणीकरण के साथ सक्रिय निर्देशिका उपयोगकर्ता जानकारी प्राप्त करें मैं एक एमवीसी 4 इंट्रानेट एप्लिकेशन पर काम कर रहा हूं और विंडोज प्रमाणीकरण का उपयोग कर रहा हूं। मैं उपयोगकर्ता ऑब्जेक्ट में जोड़ना चाहता हूं कि प्रमाणीकरण विधि (@User) का उपयोग करती है और उस डेटा को सक्रिय निर्देशिका (जैसे ईमेल, फोन नंबर इत्यादि) से प्राप्त करती है।एमवीसी 4

मुझे पता है कि मैं एक कस्टम प्राधिकरण विशेषता बना सकता हूं और इसे नियंत्रक में जोड़ सकता हूं कि मेरे सभी अन्य नियंत्रकों का उत्तराधिकारी है, लेकिन मुझे नहीं पता कि यह वही करने का सही तरीका है जो मैं चाहता हूं।

मेरा अंतिम लक्ष्य सरल है, मैं चाहता हूं कि @User ऑब्जेक्ट में अतिरिक्त गुण हो जो सक्रिय निर्देशिका के माध्यम से पॉप्युलेट हो। आप जो भी सहायताकर सकें, उसके लिए धन्यवाद।

उत्तर

28

मैं अपने मौजूदा प्रश्न को देखते हुए, इस मुद्दे के साथ दूसरों की मदद करने के लिए अपने समाधान के साथ स्टैक ओवरव्लो में अपना स्वयं का प्रश्न जोड़ने वाला था। ऐसा लगता है कि यह एक बहुत ही आम बात होगी, लेकिन इसे कैसे करना है इसके बारे में जानकारी केवल कई स्रोतों के बीच फैली हुई है और ट्रैक करने में कठोर है। केवल एक पूरा संसाधन नहीं है, इसलिए उम्मीद है कि इससे आपको और दूसरों की मदद मिलेगी।

ऐसा करने का सबसे अच्छा तरीका उपयोगकर्ता प्रिंसिपल एक्सटेंशन का उपयोग करना है। असल में, आप UserPrincipal को System.DirectoryServices.AccountManagement से उप-वर्गीकृत कर रहे हैं और अपनी अतिरिक्त संपत्तियां जोड़ रहे हैं। यह ExtensionGet और ExtensionSet (कुछ हद तक जादुई) विधियों के माध्यम से सक्षम है।

[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("user")] 
public class UserPrincipalExtended : UserPrincipal 
{ 
    public UserPrincipalExtended(PrincipalContext context) : base(context) 
    { 
    } 

    public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled) 
     : base(context, samAccountName, password, enabled) 
    { 
    } 

    [DirectoryProperty("title")] 
    public string Title 
    { 
     get 
     { 
      if (ExtensionGet("title").Length != 1) 
       return null; 

      return (string)ExtensionGet("title")[0]; 
     } 

     set 
     { 
      ExtensionSet("title", value); 
     } 
    } 

    [DirectoryProperty("department")] 
    public string Department 
    { 
     get 
     { 
      if (ExtensionGet("department").Length != 1) 
       return null; 

      return (string)ExtensionGet("department")[0]; 
     } 

     set 
     { 
      ExtensionSet("department", value); 
     } 
    } 

    public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, string identityValue) 
    { 
     return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityValue); 
    } 

    public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue) 
    { 
     return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityType, identityValue); 
    } 
} 

कक्षा के दो विशेषताओं को आपके एडी के उदाहरण में अनुकूलित करने की आवश्यकता है। DirectoryRdnPrefix के लिए मान एडी में आरडीएन (रिश्तेदार विशिष्ट नाम) होना चाहिए, जबकि DirectoryObjectClass के लिए मूल्य उपयोगकर्ता ऑब्जेक्ट क्लास के लिए AD में निर्देशिका ऑब्जेक्ट प्रकार का नाम होना आवश्यक है। एक विशिष्ट एडी डोमेन सेवा सेटअप के लिए, उन्हें दोनों को ऊपर दिए गए कोड में इस्तेमाल किया जाना चाहिए, लेकिन एलडीएस सेटअप के लिए, भिन्न हो सकता है। मैंने दो नए गुण जोड़े हैं जो मेरा संगठन "शीर्षक" और "विभाग" का उपयोग करता है। उस से, आप इस बारे में एक विचार प्राप्त कर सकते हैं कि अपनी पसंदीदा संपत्ति को कैसे जोड़ना है: मूल रूप से आप यहां दिए गए टेम्पलेट का उपयोग करके एक संपत्ति बनाते हैं। संपत्ति को आपकी पसंद की किसी भी चीज़ का नाम दिया जा सकता है, लेकिन स्ट्रिंग मान DirectoryProperty पर पास हो गया है और कोड ब्लॉक के अंदर एडी से संपत्ति के नाम से मेल खाना चाहिए। उस जगह के साथ, आप PrincipalContext का उपयोग UserPrincipal के बजाय अपने उप-वर्ग के साथ कर सकते हैं ताकि उपयोगकर्ता को आपके द्वारा जोड़े जाने वाले गुणों के साथ उपयोगकर्ता ऑब्जेक्ट वापस प्राप्त किया जा सके।

UserPrincipalExtended user = UserPrincipalExtended.FindByIdentity(
    new PrincipalContext(ContextType.Domain), User.Identity.Name); 

और UserPrincipal उदाहरण पर किसी भी अन्य की तरह अपनी संपत्ति का उपयोग:

// User's title 
user.Title 

आप System.DirectoryServices.AccountManagement.UserPrincipal से अपरिचित हैं, वहाँ कुछ उपयोगकर्ता में पकाया गुण: GivenName, Surname, DisplayName, आदि विशेष रूप से आपके परिस्थिति में, चूंकि आपने विशेष रूप से फोन और ईमेल का उल्लेख किया है, वहां VoiceTelephoneNumber और EmailAddress है। आप MSDN docs में पूरी सूची देख सकते हैं। यदि आपको केवल अंतर्निहित जानकारी की आवश्यकता है, तो आपको ऊपर दिखाए गए अनुसार UserPrincipal का विस्तार करने की आवश्यकता नहीं है। तुम बस करना होगा:

UserPrincipal user = UserPrincipal.FindByIdentity(
    new PrincipalContext(ContextType.Domain), User.Identity.Name); 

लेकिन, 10 में से 9 बार, बनाया-इन पर्याप्त नहीं होगा, तो यह कितनी आसानी से आराम पाने के लिए पता करने के लिए अच्छा है।

अंत में, मैं @using लाइनों को किसी भी दृश्य में जोड़ने के लिए नहीं जोड़ना चाहता था, इसलिए मैं आगे बढ़ गया और नामस्थान को Views फ़ोल्डर के web.config में जोड़ा।वह हिस्सा महत्वपूर्ण है, इसे Views फ़ोल्डर के web.config में जोड़ा जाना चाहिए, प्रोजेक्ट की नहीं है (और यदि आप क्षेत्र का उपयोग कर रहे हैं तो प्रत्येक क्षेत्र का व्यक्तिगत Views फ़ोल्डर)।

<system.web.webPages.razor> 
    ... 
    <pages pageBaseType="System.Web.Mvc.WebViewPage"> 
     <namespaces> 
      ... 
      <add namespace="System.DirectoryServices.AccountManagement" /> 
      <add namespace="Namespace.For.Your.Extension" /> 
     </namespaces> 
    </pages> 
</system.web.webPages.razor> 
+0

मैं इस विस्तार की तरह जोड़ने के लिए, लेकिन मैं userprincipal वर्गों के साथ अनुभव नहीं है। मैंने इस नए वर्ग के साथ अपने उपयोगकर्ता प्रिंसिपल प्रकारों को बदल दिया लेकिन स्थैतिक FindByIdentity विधि को कॉल करते समय एक त्रुटि मिली। अतिरिक्त जानकारी: टाइप प्रिंसिपल ऑब्जेक्ट्स UserPrincipalExtended का उपयोग इस स्टोर के विरुद्ध किसी क्वेरी में नहीं किया जा सकता है। किसी भी विचार पर यह क्यों विफल रहता है? –

-1
[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("user")] 

ये मान्यता प्राप्त नहीं की है। क्या आपने अभी अपनी एमवीसी 4 रेज़र परियोजना में एक नियंत्रण बनाया है?

मैं भी नहीं मिल रहा है या संदर्भ System.DirectoryServices.AccountManagement