Project

General

Profile

« Previous | Next » 

Revision 871

Added by Matt Jones about 23 years ago

Modified AuthLdap to fix the may problems associated with group and user
queries. Now the getGroups() and getUsers() methods work as advertised,
and there is a test of each of the methods in "main" for testing purposes.
Simplified the class substantially. Fixed the getAttributes method as
well. The getSubtree and getPrincipals methods have yet to be tested and
I suspect that they do not work (but we'll see). Also need to check
if "getIdentifyingName() works properly.

The problems were all associated with not setting the ldapBase correctly in
the context. The getAttributes method also incorrectly overwrote the ldapBase
and was messing up session management. I think all of the ldapBase issues
are now resolved (except in the methods that I did not check, listed above.

Now we should be able to check if group-based authentication works for
Metacat.

View differences:

src/edu/ucsb/nceas/metacat/AuthLdap.java
78 78
    this.ldapsUrl = MetaCatUtil.getOption("ldapsurl");
79 79
    this.ldapBase = MetaCatUtil.getOption("ldapbase");
80 80
    this.referral = MetaCatUtil.getOption("referral");
81
    this.referral = "ignore";
82
    System.out.println("LDAPBASE is: " + ldapBase);
81 83
  }
82 84

  
83 85
  /**
......
370 372

  
371 373
  /**
372 374
   * Get all users from the authentication service
375
   *
376
   * @param user the user for authenticating against the service
377
   * @param password the password for authenticating against the service
378
   * @returns string array of all of the user names
373 379
   */
374 380
  public String[] getUsers(String user, String password) 
375 381
         throws ConnectException
......
381 387
    env.put(Context.INITIAL_CONTEXT_FACTORY, 
382 388
            "com.sun.jndi.ldap.LdapCtxFactory");
383 389
    env.put(Context.REFERRAL, referral);
384
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
390
    env.put(Context.PROVIDER_URL, ldapUrl);
385 391

  
386 392
    try {
387 393

  
388 394
        // Create the initial directory context
389 395
        DirContext ctx = new InitialDirContext(env);
390 396

  
391
        // Specify the ids of the attributes to return
392
        String[] attrIDs = {"uid"};
393

  
394 397
        // Specify the attributes to match.
395 398
        // Users are objects that have the attribute objectclass=InetOrgPerson.
396
        Attributes matchAttrs = new BasicAttributes(true); // ignore case
397
        matchAttrs.put(new BasicAttribute("objectclass", "inetOrgPerson"));
398

  
399
        // Search for objects in the current context
400
        NamingEnumeration enum = ctx.search("", matchAttrs, attrIDs);
401

  
399
        SearchControls ctls = new SearchControls();
400
        String[] attrIDs = {"dn"};
401
        ctls.setReturningAttributes(attrIDs);
402
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
403
        String filter = "(objectClass=inetOrgPerson)";
404
        NamingEnumeration enum = ctx.search(ldapBase, filter, ctls);
405
        
402 406
        // Print the users
403 407
        Vector uvec = new Vector();
404 408
        while (enum.hasMore()) {
405 409
          SearchResult sr = (SearchResult)enum.next();
406
          Attributes attrs = sr.getAttributes();
407
          NamingEnumeration enum1 = attrs.getAll(); // only "uid" attr
408
          while (enum1.hasMore()) {
409
            Attribute attr = (Attribute)enum1.next();
410
            uvec.add(attr.get());
411
          }
410
          uvec.add(sr.getName()+","+ldapBase);
412 411
        }
413 412

  
414 413
        // initialize users[]; fill users[]
......
422 421

  
423 422
    } catch (NamingException e) {
424 423
      System.err.println("Problem getting users in AuthLdap.getUsers:" + e);
424
      e.printStackTrace(System.err);
425 425
      throw new ConnectException(
426 426
      "Problem getting users in AuthLdap.getUsers:" + e);
427 427
    }
......
431 431

  
432 432
  /**
433 433
   * Get the users for a particular group from the authentication service
434
   *
435
   * @param user the user for authenticating against the service
436
   * @param password the password for authenticating against the service
437
   * @param group the group whose user list should be returned
438
   * @returns string array of the user names belonging to the group
434 439
   */
435 440
  public String[] getUsers(String user, String password, String group) 
436 441
         throws ConnectException
......
442 447
    env.put(Context.INITIAL_CONTEXT_FACTORY, 
443 448
            "com.sun.jndi.ldap.LdapCtxFactory");
444 449
    env.put(Context.REFERRAL, referral);
445
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
450
    env.put(Context.PROVIDER_URL, ldapUrl);
446 451

  
447 452
    try {
448 453

  
......
450 455
        DirContext ctx = new InitialDirContext(env);
451 456

  
452 457
        // Specify the ids of the attributes to return
453
        String[] attrIDs = {"uniquemember"};
458
        String[] attrIDs = {"uniqueMember"};
454 459

  
455
        // Specify the attributes to match.
456
        // Groups are objects with attribute objectclass=groupofuniquenames.
457
        Attributes matchAttrs = new BasicAttributes(true); // ignore case
458
        matchAttrs.put(new BasicAttribute("objectclass", "groupofuniquenames"));
459
        matchAttrs.put(new BasicAttribute("cn", group));
460
        Attributes answer = ctx.getAttributes(group, attrIDs);
460 461

  
461
        // Search for objects in the current context
462
        NamingEnumeration enum = ctx.search("", matchAttrs, attrIDs);
463

  
464
        // Print the users
465 462
        Vector uvec = new Vector();
466
        while (enum.hasMore()) {
467
          SearchResult sr = (SearchResult)enum.next();
468
          Attributes attrs = sr.getAttributes();
469
          // return all attributes (only "uniquemember" attr)
470
          NamingEnumeration enum1 = attrs.getAll();
471
          while (enum1.hasMore()) {
472
            Attribute attr = (Attribute)enum1.next();
473
            // return all values of that attribute
474
            NamingEnumeration enum2 = attr.getAll();
475
            while (enum2.hasMore()) {
476
              // get DN of a member
477
              String memberDN = (String)enum2.next();
478
              try {
479
                // we actually need RDN of the member
480
                // try to get RDN (UID) of the member in case of a user
481
                String memberID = getUserID(memberDN);
482
                if ( memberID != null ) {
483
                  uvec.add(memberID);
484
                // CURRENTLY WE DON'T SUPPORT SUBGROUPING, THUS
485
                // IGNORE SUBGROUPS AS MEMBERS OF THE GROUP
486
                // // this is a group, not user
487
                // // try to get RDN (CN) of the group
488
                // } else {
489
                //   memberID = getGroupID(memberDN);
490
                //   uvec.add(memberID);
491
                }
492
              } catch (NamingException ne) {}
493
            }
494
          }
463
        for (NamingEnumeration ae = answer.getAll(); ae.hasMore();) {
464
            Attribute attr = (Attribute)ae.next();
465
            for (NamingEnumeration e = attr.getAll(); e.hasMore();
466
                 uvec.add(e.next()) 
467
                 );
495 468
        }
496 469

  
497 470
        // initialize users[]; fill users[]
......
504 477
        ctx.close();
505 478

  
506 479
    } catch (NamingException e) {
507
      System.err.println("Problem getting users for a group in AuthLdap.getUsers:" + e);
480
      System.err.println("Problem getting users for a group in " +
481
              "AuthLdap.getUsers:" + e);
508 482
      throw new ConnectException(
509 483
      "Problem getting users for a group in AuthLdap.getUsers:" + e);
510 484
    }
......
513 487
  }
514 488

  
515 489
  /**
516
   * Get UID by DN of a member
517
   */
518
  private String getUserID(String dn) 
519
         throws NamingException
520
  {
521
    String[] users = null;
522

  
523
    // Identify service provider to use
524
    Hashtable env = new Hashtable(11);
525
    env.put(Context.INITIAL_CONTEXT_FACTORY, 
526
            "com.sun.jndi.ldap.LdapCtxFactory");
527
    env.put(Context.REFERRAL, referral);
528
    env.put(Context.PROVIDER_URL, ldapUrl); // + ldapBase);
529

  
530
    try {
531

  
532
        // Create the initial directory context
533
        DirContext ctx = new InitialDirContext(env);
534

  
535
        // Specify the ids of the attributes to return
536
        String[] attrIDs = {"uid"};
537

  
538
        // Ask for "uid" attributes of the user 
539
        Attributes attrs = ctx.getAttributes(dn, attrIDs);
540

  
541
        // Print all of the attributes (only "uid" attr)
542
        Vector uvec = new Vector();
543
        NamingEnumeration en = attrs.getAll();
544
        while (en.hasMore()) {
545
          Attribute att = (Attribute)en.next();
546
          Vector values = new Vector();
547
          String attName = att.getID();
548
          NamingEnumeration attvalues = att.getAll();
549
          while (attvalues.hasMore()) {
550
            String value = (String)attvalues.next();
551
            values.add(value);
552
          }
553
          uvec.add(values.elementAt(0));
554
        }
555

  
556
        // initialize users[]; fill users[]
557
        users = new String[uvec.size()];
558
        for (int i=0; i < uvec.size(); i++) {
559
          users[i] = (String)uvec.elementAt(i); 
560
        }
561

  
562
        // Close the context when we're done
563
        ctx.close();
564

  
565
    } catch (NamingException ne) {
566
      System.err.println("Problem getting userID by \"dn\" in AuthLdap.getUserID:" + ne);
567
      throw ne;
568
    }
569

  
570
    if ( users.length > 0 ) {
571
      return users[0];
572
    }
573
    return null;
574
  }
575

  
576
  /**
577
   * Get CN by DN of a member
578
   */
579
  private String getGroupID(String dn) 
580
         throws NamingException
581
  {
582
    String[] groups = null;
583

  
584
    // Identify service provider to use
585
    Hashtable env = new Hashtable(11);
586
    env.put(Context.INITIAL_CONTEXT_FACTORY, 
587
            "com.sun.jndi.ldap.LdapCtxFactory");
588
    env.put(Context.REFERRAL, referral);
589
    env.put(Context.PROVIDER_URL, ldapUrl); // + ldapBase);
590

  
591
    try {
592

  
593
        // Create the initial directory context
594
        DirContext ctx = new InitialDirContext(env);
595

  
596
        // Specify the ids of the attributes to return
597
        String[] attrIDs = {"cn"};
598

  
599
        // Ask for "uid" attributes of the user 
600
        Attributes attrs = ctx.getAttributes(dn, attrIDs);
601

  
602
        // Print all of the attributes (only "cn" attr)
603
        Vector uvec = new Vector();
604
        NamingEnumeration en = attrs.getAll();
605
        while (en.hasMore()) {
606
          Attribute att = (Attribute)en.next();
607
          Vector values = new Vector();
608
          String attName = att.getID();
609
          NamingEnumeration attvalues = att.getAll();
610
          while (attvalues.hasMore()) {
611
            String value = (String)attvalues.next();
612
            values.add(value);
613
          }
614
          uvec.add(values.elementAt(0));
615
        }
616

  
617
        // initialize users[]; fill users[]
618
        groups = new String[uvec.size()];
619
        for (int i=0; i < uvec.size(); i++) {
620
          groups[i] = (String)uvec.elementAt(i); 
621
        }
622

  
623
        // Close the context when we're done
624
        ctx.close();
625

  
626
    } catch (NamingException ne) {
627
      System.err.println("Problem getting groupID by \"dn\" in AuthLdap.getGroupID:" + ne);
628
      throw ne;
629
    }
630

  
631
    if ( groups.length > 0 ) {
632
      return groups[0];
633
    }
634
    return null;
635
  }
636

  
637
  /**
638 490
   * Get all groups from the authentication service
491
   *
492
   * @param user the user for authenticating against the service
493
   * @param password the password for authenticating against the service
494
   * @returns string array of the group names
639 495
   */
640 496
  public String[] getGroups(String user, String password) 
641 497
         throws ConnectException
642 498
  {
643
    String[] groups = null;
644

  
645
    // Identify service provider to use
646
    Hashtable env = new Hashtable(11);
647
    env.put(Context.INITIAL_CONTEXT_FACTORY, 
648
            "com.sun.jndi.ldap.LdapCtxFactory");
649
    env.put(Context.REFERRAL, referral);
650
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
651

  
652
    try {
653
        // Create the initial directory context
654
        DirContext ctx = new InitialDirContext(env);
655
        // Specify the ids of the attributes to return
656
        String[] attrIDs = {"cn"};
657

  
658
        // Specify the attributes to match.
659
        // Groups are objects with attribute objectclass=groupofuniquenames.
660
        Attributes matchAttrs = new BasicAttributes(true); // ignore case
661
        matchAttrs.put(new BasicAttribute("objectclass", "groupofuniquenames"));
662
        // Search for objects in the current context
663
        NamingEnumeration enum = ctx.search("", matchAttrs, attrIDs);
664

  
665
        // Print the users
666
        Vector uvec = new Vector();
667
        while (enum.hasMore()) {
668
          SearchResult sr = (SearchResult)enum.next();
669
          Attributes attrs = sr.getAttributes();
670
          NamingEnumeration enum1 = attrs.getAll(); // only "cn" attr
671
          while (enum1.hasMore()) {
672
            Attribute attr = (Attribute)enum1.next();
673
            uvec.add(attr.get());
674
          }
675
        }
676

  
677
        // initialize groups[] and fill it
678
        groups = new String[uvec.size()];
679
        for (int i=0; i < uvec.size(); i++) {
680
          groups[i] = (String)uvec.elementAt(i); 
681
        }
682

  
683
        // Close the context when we're done
684
        ctx.close();
685

  
686
    } catch (NamingException e) {
687
      System.err.println("Problem getting groups in AuthLdap.getGroups 1:" + e);
688
      throw new ConnectException(
689
      "Problem getting groups in AuthLdap.getGroups:" + e);
690
    }
691

  
692
    return groups;
499
      return getGroups(user, password, null);
693 500
  }
694 501

  
695 502
  /**
696 503
   * Get the groups for a particular user from the authentication service
504
   *
505
   * @param user the user for authenticating against the service
506
   * @param password the password for authenticating against the service
507
   * @param foruser the user whose group list should be returned
508
   * @returns string array of the group names
697 509
   */
698 510
  public String[] getGroups(String user, String password, String foruser) 
699 511
         throws ConnectException
......
706 518
    env.put(Context.INITIAL_CONTEXT_FACTORY, 
707 519
            "com.sun.jndi.ldap.LdapCtxFactory");
708 520
    env.put(Context.REFERRAL, referral);
709
    //System.out.println("GG server: " + ldapUrl + ldapBase); 
710
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
521
    env.put(Context.PROVIDER_URL, ldapUrl);
711 522
    try {
712 523

  
713 524
        // Create the initial directory context
......
717 528
        // Specify the attributes to match.
718 529
        // Groups are objects with attribute objectclass=groupofuniquenames.
719 530
        // and have attribute uniquemember: uid=foruser,ldapbase.
720
        Attributes matchAttrs = new BasicAttributes(); // ignore case
721
        matchAttrs.put(new BasicAttribute("objectClass", "groupOfUniqueNames"));
722
        //System.out.println("GG user: " + user);
723
        //System.out.println("GG foruser: " + foruser);
724
        String dn = user;/*getIdentifyingName(foruser, ldapUrl, ldapBase);*/ 
725
        //System.out.println("GG dn: " + dn);
726
        matchAttrs.put(new BasicAttribute("uniqueMember", dn));
727
        // Search for objects in the current context
728
        //System.out.println("GG matchAttrs: " + matchAttrs.toString());
729
        NamingEnumeration enum = ctx.search("", matchAttrs, attrIDs);
730
        // Print the users
531
        SearchControls ctls = new SearchControls();
532
        ctls.setReturningAttributes(attrIDs);
533
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
534
        
535
        String filter = null;
536
        String gfilter = "(objectClass=groupOfUniqueNames)";
537
        if (null == foruser) {
538
            filter = gfilter;
539
        } else {
540
            filter = "(& " + gfilter + "(uniqueMember=" + foruser + "))";
541
        }
542
        NamingEnumeration enum = ctx.search(ldapBase, filter, ctls);
543

  
544
        // Print the groups
731 545
        Vector uvec = new Vector();
732 546
        while (enum.hasMore()) {
733
          //System.out.println("GG search result found");
734 547
          SearchResult sr = (SearchResult)enum.next();
735
          Attributes attrs = sr.getAttributes();
736
          NamingEnumeration enum1 = attrs.getAll(); // only "cn" attr
737
          while (enum1.hasMore()) {
738
            Attribute attr = (Attribute)enum1.next();
739
            uvec.add(attr.get());
740
          }
548
          uvec.add(sr.getName()+","+ldapBase);
741 549
        }
742 550

  
743 551
        // initialize groups[] and fill it
744
        //System.out.println("GG getting groups: " + uvec.size());
745 552
        groups = new String[uvec.size()];
746 553
        for (int i=0; i < uvec.size(); i++) {
747
          //System.out.println("GG group: " + groups[i]);
748 554
          groups[i] = (String)uvec.elementAt(i); 
749 555
        }
750 556

  
......
763 569
  /**
764 570
   * Get attributes describing a user or group
765 571
   *
766
   * @param user the user for which the attribute list is requested
572
   * @param foruser the user for which the attribute list is requested
767 573
   * @returns HashMap a map of attribute name to a Vector of values
768 574
   */
769 575
  public HashMap getAttributes(String foruser) 
......
775 581
  /**
776 582
   * Get attributes describing a user or group
777 583
   *
778
   * @param user the user for which the attribute list is requested
779
   * @param authuser the user for authenticating against the service
584
   * @param user the user for authenticating against the service
780 585
   * @param password the password for authenticating against the service
586
   * @param foruser the user whose attributes should be returned
781 587
   * @returns HashMap a map of attribute name to a Vector of values
782 588
   */
783 589
  public HashMap getAttributes(String user, String password, String foruser) 
......
787 593
    String ldapUrl = this.ldapUrl;
788 594
    String ldapBase = this.ldapBase;
789 595
    String userident = foruser;
596
    /*
790 597
    try { 
791 598
      this.ldapBase = userident.substring(userident.indexOf(",")+1);
792 599
      userident = userident.substring(0,userident.indexOf(","));
793 600
    } catch (StringIndexOutOfBoundsException e) {}
794

  
601
*/
795 602
    // Identify service provider to use
796 603
    Hashtable env = new Hashtable(11);
797 604
    env.put(Context.INITIAL_CONTEXT_FACTORY, 
798 605
        "com.sun.jndi.ldap.LdapCtxFactory");
799 606
    env.put(Context.REFERRAL, referral);
800
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
607
    env.put(Context.PROVIDER_URL, ldapUrl);
801 608

  
802 609
    try {
803 610
      
......
805 612
      DirContext ctx = new InitialDirContext(env);
806 613
        
807 614
      // Find out the identifying attribute for the user
808
      userident = getIdentifyingName(userident,ldapUrl,ldapBase);
615
      //userident = getIdentifyingName(userident,ldapUrl,ldapBase);
809 616

  
810 617
      // Ask for all attributes of the user 
811
      Attributes attrs = ctx.getAttributes(userident);
618
      //Attributes attrs = ctx.getAttributes(userident);
619
      Attributes attrs = ctx.getAttributes(foruser);
812 620
 
813 621
      // Print all of the attributes
814 622
      NamingEnumeration en = attrs.getAll();
......
827 635
      // Close the context when we're done
828 636
      ctx.close();
829 637
    } catch (NamingException e) {
830
      System.err.println("Problem getting attributes in AuthLdap.getAttributes:" 
831
                          + e);
638
      System.err.println("Problem getting attributes in " + 
639
              "AuthLdap.getAttributes:" + e);
832 640
      throw new ConnectException(
833 641
      "Problem getting attributes in AuthLdap.getAttributes:" + e);
834 642
    }
......
1003 811
      isValid = authservice.authenticate(user, password);
1004 812
      if (isValid) {
1005 813
        System.out.println("Authentication successful for: " + user );
1006
        System.out.println(" ");
1007
        
1008 814
      } else {
1009 815
        System.out.println("Authentication failed for: " + user);
1010 816
      }
1011 817

  
818
      // Get attributes for the user
1012 819
      if (isValid) {
1013
        //String group = args[2];
1014
        HashMap userInfo = authservice.getAttributes(user, password, "knb");
820
        System.out.println("\nGetting attributes for user....");
821
        HashMap userInfo = authservice.getAttributes(user, password, user);
1015 822
        // Print all of the attributes
1016 823
        Iterator attList = (Iterator)(((Set)userInfo.keySet()).iterator());
1017 824
        while (attList.hasNext()) {
......
1023 830
            System.out.println(att + ": " + value);
1024 831
          }
1025 832
        }
833
      }
1026 834

  
835
      // get the groups
836
      if (isValid) {
837
        System.out.println("\nGetting all groups....");
838
        String[] groups = authservice.getGroups(user, password);
839
        System.out.println("Groups found: " + groups.length);
840
        for (int i=0; i < groups.length; i++) {
841
            System.out.println("Group " + i + ": " + groups[i]);
842
        }
1027 843
      }
1028 844

  
845
      // get the groups for the user
846
      String savedGroup = null;
847
      if (isValid) {
848
        System.out.println("\nGetting groups for user....");
849
        String[] groups = authservice.getGroups(user, password, user);
850
        System.out.println("Groups found: " + groups.length);
851
        for (int i=0; i < groups.length; i++) {
852
            System.out.println("Group " + i + ": " + groups[i]);
853
            savedGroup = groups[i];
854
        }
855
      }
856

  
857
      // get the users for a group
858
      if (isValid) {
859
        System.out.println("\nGetting users for group....");
860
        System.out.println("Group: " + savedGroup);
861
        String[] users = authservice.getUsers(user, password, savedGroup);
862
        System.out.println("Users found: " + users.length);
863
        for (int i=0; i < users.length; i++) {
864
            System.out.println("User " + i + ": " + users[i]);
865
        }
866
      }
867

  
868
      // get all users
869
      if (isValid) {
870
        System.out.println("\nGetting all users ....");
871
        String[] users = authservice.getUsers(user, password);
872
        System.out.println("Users found: " + users.length);
873
        for (int i=0; i < users.length; i++) {
874
            System.out.println("User " + i + ": " + users[i]);
875
        }
876
      }
877
/*
1029 878
      // get the whole list groups and users in XML format
1030 879
      if (isValid) {
880
        System.out.println("\nTrying principals....");
1031 881
        authservice = new AuthLdap();
1032 882
        String out = authservice.getPrincipals(user, password);
1033 883
        java.io.File f = new java.io.File("principals.xml");
......
1038 888
        buff.close();
1039 889
        fw.close();
1040 890
      }
1041

  
891
*/
1042 892
    } catch (ConnectException ce) {
1043 893
      System.err.println(ce.getMessage());
1044 894
    } catch (java.io.IOException ioe) {

Also available in: Unified diff