2012-02-16 1 views
0

userProxy 개체를 사용하여 Active Directory와 Active Directory Ligthweight Directory Services (AD LDS)를 동기화했습니다. 또한 AD LDS에 사용자 클래스 개체를 만듭니다.여러 DirectoryObjectClassAttribute가있는 System.DirectoryServices.AccountManagement.UserPrincipal

UserPrincipal 개체는 AD의 사용자 클래스 개체로 제한된 것처럼 보입니다. userProxy 클래스 객체를 기반으로 userProxyPrincipal을 만들 수 있다는 것을 알고 있습니다. 그러나 두 경우 모두를 처리 할 단일 개체를 만들고 싶습니다.

DirectoryObjectClassAttribute의 문서에서 여러 DirectoryObjectClassAttribute를 사용할 수 있으므로이 작업을 수행하는 방법이 궁금합니다.

두 개의 속성 ("user"및 "userProxy"가있는 속성)을 가진 자체 UserPrincipal 객체를 지정하면 컴파일되지만 첫 번째 것과 동일한 클래스의 객체 만 일치시킵니다. (나는 그것들을 바꾸려고 시도했다. 그리고 항상 일치하는 첫 번째 것이다.)

속성에 두 개의 DirectoryPropertyAttribute를 지정하면 두 번째 것과 같은 클래스의 객체 만 일치하게된다.

그래서 나는 그것을 다른 것으로 옮길 수 있다는 것을 알지만, 올바르게 구현하는 방법을 이해하지 못합니다.

제안 사항?

(코드 exemple의 부족에 대한 미안 해요, 난 집에있어 그들에게 직장에서 제일 먼저 내일 게시 할 예정입니다)

업데이트 -

가 여기 내 UserProxyPrincipal 클래스의 코드 Snipet 추가

여기

namespace System.DirectoryServices.AccountManagement 
{ 
    [DirectoryRdnPrefix("CN")] 
    [DirectoryObjectClass("userProxy")] 
    [DirectoryObjectClass("user")] 
    public class UserProxyPrincipal : UserPrincipal 
    { 
     public UserProxyPrincipal(PrincipalContext context) 
      : base(context) { } 
     public UserProxyPrincipal(PrincipalContext context, string samAccountName, string password, bool enabled) 
      : base(context, samAccountName, password, enabled) { } 

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

     [DirectoryProperty("objectSid")] 
     public string ObjectSid 
     { 
      get 
      { 
       var values = ExtensionGet("objectSid"); 
       return ((values != null) && (values.Length > 0) ? values[0].ToString() : null); 
      } 
      set { ExtensionSet("objectSid", value); } 
     } 

     [DirectoryProperty("name")] 
     public new string Name 
     { 
      get 
      { 
       var values = ExtensionGet("name"); 
       return ((values != null) && (values.Length > 0) ? values[0].ToString() : null); 
      } 
      set { ExtensionSet("name", value); } 
     } 
    } 
} 
그것을

namespace FunWith.MTO.Framework.Security 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      PrincipalContext context = new PrincipalContext(ContextType.ApplicationDirectory, "servername.some.domain:636", "DC=dev,DC=local", ContextOptions.SimpleBind); 
      Console.WriteLine("Log AdamUser : {0}", context.ValidateCredentials("AdamUser", "somePassword%")); 
      Console.WriteLine("Log AdProxiedUser : {0}", context.ValidateCredentials("AdProxiedUser", "somePassword;")); 
      var p = UserProxyPrincipal.FindByIdentity(context, "AdProxiedUser"); 
      var t = UserProxyPrincipal.FindByIdentity(context, "AdamUser"); 
      Console.WriteLine("User AdProxiedUser is {0}" ,p != null ? p.DistinguishedName : "null"); 
      Console.WriteLine("User AdamUser is {0}", t != null ? t.DistinguishedName : "null"); 

     } 
    } 
} 
을 테스트하는 프로그램입니다 나는 그렇게 내 UserProxyPrincipal에있는 두 개의 DirectoryObjectClass을 교환하면 지금

 
    Log AdamUser : True 
    Log AdProxiedUser : True 
    User AdProxiedUser is CN=AdProxiedUser,OU=Usagers,DC=dev,DC=local 
    User AdamUser is null 

:

[DirectoryObjectClass("user")] 
    [DirectoryObjectClass("userProxy")] 

나는이 결과를 가지고 (교환 결과) :

게시 된 코드 내 출력입니다

 
    Log AdamUser : True 
    Log AdProxiedUser : True 
    User AdProxiedUser is null 
    User AdamUser is CN=AdamUser,OU=AdamUsers,OU=Usagers,DC=dev,DC=local 

두 개의 서로 다른 DirectoryObjectClassAttribute를 정의 할 수 있음을 알았 기 때문에 필자는 다른 견본을 설정해야한다고 생각하기 시작했습니다. DirectoryPropertyAttri 그런 뷰트 : 다시 교환 결과를 하나의 결과

[DirectoryProperty("objectSid")] 
    [DirectoryProperty("objectSid")] 
    public string ObjectSid 
     [...] 

    [DirectoryProperty("name")] 
    [DirectoryProperty("name")] 
    public new string Name 
     [...] 

, 즉 내 문제

오의 이해와 방법으로 도움이 될 것입니다 희망

 
    Log AdamUser : True 
    Log AdProxiedUser : True 
    User AdProxiedUser is CN=AdProxiedUser,OU=Usagers,DC=dev,DC=local 
    User AdamUser is null 

(I는 교환 DirectoryObjectClassAttribute을 유지) 이중 속성을 제거하면이 속성 만 유지됩니다.

[DirectoryObjectClass("userProxy")] 

그리고 특별히 그런 내 AdamUser (사용자 개체 클래스) 내 AdProxiedUser (userProxy 개체 클래스) 내 UserProxyPrincipal에 대한 UserPrincipal를 사용

var p = UserProxyPrincipal.FindByIdentity(context, "AdProxiedUser"); 
var t = UserProxy.FindByIdentity(context, "AdamUser"); 

모두 일치한다. 결과 참고 :이 질문은 나를 위해 감각이

 
    Log AdamUser : True 
    Log AdProxiedUser : True 
    User AdProxiedUser is CN=AdProxiedUser,OU=Usagers,DC=dev,DC=local 
    User AdamUser is CN=AdamUser,OU=AdamUsers,OU=Usagers,DC=dev,DC=local 

답변

0

하더라도 나는 대답은 지금까지 내가 Query filter ArgumentException when trying to extending OU principal에 제공 한 것과 아니라고 생각합니다.

요점은 Active Directory (및 ADAM/LDS)는 다른 디렉터리와 마찬가지로 클래스 계층 구조의 개념으로 구축된다는 것입니다. 따라서 DirectoryObjectClass를 사용하여 스키마 계층 구조 트리의 분기에서 클래스를 지정하지만 다른 분기에서 두 클래스를 지정할 수는 없습니다.

필자가 원하는대로하려면 userProxy 클래스는 사용자 스키마의 하위 클래스이거나 역순이어야합니다. 즉, C#을 사용하여 디렉토리 스키마의 두 클래스 (다른 분기)에서 상속하는 클래스를 만들고 C# 디렉토리는 다중 상속을 지원하지 않으므로 빌드를 시도합니다.

글을 쓰면서 나는 당신의 질문에 답하지 않고 왜 그것이 작동하지 않는지 설명하려고 노력한다.

+0

흥미로운 점, 나는 그것을 점검하고 실행 가능한지 확인합니다. 그렇다면 내 문제를 해결하는 경우 참조하십시오. – Groumy

2

오래 전 (2 년) 게시되었습니다.그러나 나는 비슷한 문제를 해결하기 위해 나섰다. 저는 "GeneralPrincipal"을 기본 클래스 "Principal"에서 상속 받아 컴퓨터, 그룹 및 사용자를 동시에 쿼리 할 수있게하려고했습니다.

internal static string ReadStructuralObjectClass(Type principalType) 
{ 
    DirectoryObjectClassAttribute[] attributeArray = (DirectoryObjectClassAttribute[]) Attribute.GetCustomAttributes(principalType, typeof(DirectoryObjectClassAttribute), false); 
    if (attributeArray == null) 
    { 
     return null; 
    } 
    string objectClass = null; 
    for (int i = 0; i < attributeArray.Length; i++) 
    { 
     if (!attributeArray[i].Context.HasValue && (objectClass == null)) 
     { 
      objectClass = attributeArray[i].ObjectClass; 
     } 
    } 
    return objectClass; 
} 

내가 그것을 해결 방법 :

첫째, 나는 (리플렉터 클래스 System.DirectoryServices.AccountManagement.ExtensionHelper) 사용되는 DirectoryObjectClassAttributes의 한 추측

나는 "바보"는 독자 다음과 같이 수행하여 속성의합니다 (DirectoryObjectClassAttribute 보면) :

[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("*)(|(objectClass=computer)(objectClass=group)(objectClass=user)")] 
public class GeneralPrincipal : Principal 
{ 
    private static readonly FieldInfo _unpersistedField = typeof(Principal).GetField("unpersisted", BindingFlags.Instance | BindingFlags.NonPublic); 

    #region Constructors 

    public GeneralPrincipal(PrincipalContext context) 
    { 
     if(context == null) 
      throw new ArgumentNullException("context"); 

     this.ContextRaw = context; 
     _unpersistedField.SetValue(this, true); 
    } 

    #endregion 
} 

희망이 도움이 누군가

감사합니다. 한스

+0

Kinderg,'[DirectoryObjectClass ("*) (| (objectClass = computer) (objectClass = group) (objectClass = user)")]'이렇게 많은 시간을 절약 할 수있었습니다! 고맙습니다. – smr5

관련 문제