# Werte aus ActiveDirectory auslesen



## Joltan (14. Jun 2007)

Hallo, nach etwas Sucherei und Recherche bin ich immer noch nicht schlauer und frage deshalb mal hier:

Ich möchte bestimmte Informationen des gerade angemeldeten Benutzers aus dem ActiveDirectory der Domäne lesen. Im Grunde brauche ich nur die dort hinterlegte eMail-Adresse, um sie dem Nutzer in einem Dialog als Defaultwert anbieten zu können. Nichts wildes also - denke ich mal so (naiv, wie ich bin).

Aus dem JNDI-Tutorial habe ich mir mal folgendes zusammengeklaubt:

```
Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://localhost:389");
        try{
            ctx = new InitialDirContext(env);
            txtOutput.setText("INIT successfull!");
        } catch (Exception ex)
        {
            txtOutput.setText("INIT failed!\nMessage: "+ex.getMessage() + "\nType: " + ex.getClass().getName());
        }
```
Ich bekomme allerdings als ergebnis immer eine javax.naming.CommunicationException ("Connection refused: connect"). Ohne jetzt auf Drittanbieterbibliotheken auszuweichen: wie kann ich das machen, wo liegt mein Fehler?


----------



## Joltan (15. Jun 2007)

Ok, die javax.naming.CommunicationException habe ich inzwischen überwunden - da mein lokaler Rechner in der Domäne ist, mußte ich natürlich den korrekten Domainserver angeben. Die Erstellung des DirContext klappt jetzt also. Jetzt muß ich es nur noch schaffen die (bestehende)  Benutzerauthentifizierung nutzen zu können um auch tatsächlich Werte auslesen zu können, ohne das der Benutzer sich nochmals an der Domäne anmelden muß...


----------



## Joltan (19. Jun 2007)

Ok, also ich komme offensichtlich nicht weiter:

Ich kann mich bei Kerberos und dem System authorisieren und bekomme einen entsprechenden LoginContext. Nun sollte ich mit der Subject.DoAs- bzw. der Subject.DoAsPrivileged-Methode eigentlich auf das ActiveDirectory zugreifen können. Also habe ich mir eine Klasse gebaut, die PrivilegedAction implementiert, die ich mit verschiedenen IADWorker-Objekten füttern kann, welche die konkreten Abfragen kapseln, und die dann mit dem Subject aus meinem LoginContext ausgeführt werden.

Trotzdem bekomme ich einen Fehler:


> ADContextWorker: ERROR while processing!
> Message: [LDAP: error code 1 - 00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece]
> Type: javax.naming.NamingException
> Cause: null



Wenn ich zusätzlich *env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");* beim Öffnen des InitialContext angebe, dann result es in folgender Fehlermeldung:


> ADContextWorker: ERROR while processing!
> Message: GSSAPI
> Type: javax.naming.AuthenticationException
> Cause: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]


Der Punkt ist, daß ich ja bei Kerberos bereits angemeldet bin (erfolgreicher LoginContext.login()), und daher doch eigentlich mit dem entsprechenden Subject einfach meine Methode mit den entsprechenden Berechtigungen ausführen können sollte, oder? Wo fehlt noch was???

Die aufrufende Methode:

```
public static IADWorker DoWork(IADWorker pWorker){
        ADDirContextWorker pDCW = new ADDirContextWorker(pWorker);
        AccessControlContext acc = AccessController.getContext();
        Subject pSubj = ADTool.GetLoginContext().getSubject().getSubject(acc);
        Subject.doAsPrivileged(pSubj,pDCW,acc);
        return pDCW.GetADWorker();
}
```

Die PrivilegedAction-Klasse

```
public class ADDirContextWorker implements PrivilegedAction {
    private IADWorker pWorker;
    DirContext pDirCtx = null;

    public ADDirContextWorker(IADWorker pWorker)
    {
        this.pWorker = pWorker;
    }
    
    public IADWorker GetADWorker(){
        return this.pWorker;
    }

    public Object run() {
	return performJndiOperation();
    }

    private boolean performJndiOperation() {

	Hashtable env = new Hashtable();
	env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
	env.put(Context.PROVIDER_URL, ADTool.GetProviderURL());
        
        try{
            System.out.println("ADContextWorker: Trying to inistantiate new DirContext with ProviderURL");
	    pDirCtx = new InitialDirContext(env);
            System.out.println("ADContextWorker: DirContext successfully set!");
            System.out.println("ADContextWorker: '"+pWorker.getClass().getName()+"' worker started!");
            pWorker.DoWork(pDirCtx);
            System.out.println("ADContextWorker: Worker finished!");
            return true;
        }
        catch (Exception ex)
        {
            System.out.println("ADContextWorker: ERROR while processing!\n   Message: "+ex.getMessage()
            + "\n   Type: " + ex.getClass().getName()
             + "\n   Cause: " + ex.getCause());
            return false;
	}
        finally
        {
            if(pDirCtx != null)
            { 
                try {
                    pDirCtx.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}
```

Mein IADWorker-Interface:

```
public interface IADWorker {
    public void DoWork(DirContext pDirContext) throws Exception;
}
```


----------

