Spring Bootにおいて、LDAPを用いてユーザ情報を一括管理する例


多くの場合、私達はシステムを構築する時、自分でユーザー管理システムを作ります。これは開発者にとっては難しいことではありませんが、複数の異なるシステムを維持し、同じユーザがシステムをまたいで使う場合、各システムが自分のユーザ情報を守ると、ユーザ情報の同期が面倒になります。ユーザー自身にとっても迷惑なので、システムのパスワードが違ったりしやすいです。このときLDAPを導入して、ユーザの基本情報を集中的に記憶し、統一した読み書きインターフェースとチェック機構を提供すると、このような問題は比較的解決しやすい。ここでは、Spring Bootを使って開発した場合、LDAPサービスにどうやってアクセスするかを説明します。
LDAP概要
LDAP(ライト級ディレクトリアクセスプロトコル、Lightweight Directory Access Protocol)は、ディレクトリサービスと呼ばれる情報サービスを提供することを実現するものです。ディレクトリサービスは、読み取り、閲覧、検索に特化した特別なデータベースシステムです。カタログは、一般的に、説明性を含む、属性に基づく情報と、微細で複雑なフィルタリング能力をサポートするために使用される。カタログは一般的に、大量の更新操作に必要な複雑な事務管理や巻き戻し戦略をサポートしていません。カタログサービスの更新は普通はとても簡単です。このカタログは、個人情報、ウェブリンク、jpeg画像などの各種情報を記憶することができる。ディレクトリに格納されている情報にアクセスするためには、TCP/IPの上で動作するアクセスプロトコル、LDAPを使用する必要があります。
LDAPディレクトリの情報は、ツリー型構造に従って組織され、特定の情報はエントリ(entry)のデータ構造に格納される。項目は関係データベースのテーブルのレコードに相当します。項目は、別名DN(Dispingushed Name)を持つ属性であり、DNは引用条の目的であり、DNは関係データベーステーブルのキーワード(Primary Key)に相当する。属性はタイプ(Type)と一つ以上の値(Values)からなり、関係データベースのフィールド(Field)はフィールド名とデータタイプから構成されていますが、検索を容易にするためには、LDAPのTypeは関係データベースのデータを低減するための冗長性要求ではなく、複数のValueがあります。LDAPにおけるエントリの組織は、一般的に地理的位置と組織的関係に従って組織され、非常に直観的である。LDAPはデータをファイルに保存し、効率を高めるために、リレーショナルデータベースではなくインデックスベースのファイルデータベースを使用することができる。タイプの一例はメールで、その値はメールアドレスになります。
LDAPの情報はツリー型の構造で保存されており、樹根には国(c=CN)またはドメイン名(dc=com)が一般的に定義されており、その下で一つ以上の組織(organization)(o=Acme)または組織ユニット(organizational units)(ou=People)が定義されている。組織ユニットは、従業員全員、ビル内のすべてのプリンタなどの情報を含むことができる。また、LDAPは、エントリが可能であり、どのような属性をサポートしなければならないかを制御するためにサポートしています。これは、オブジェクトカテゴリと呼ばれる特殊な属性を持っています。属性の値は、このエントリが従わなければならないいくつかの規則を決定し、このエントリが、少なくともどの属性を含むべきかを規定している。例えば、inetorg Personオブジェクト類はsn(surname)とcn(common name)属性をサポートする必要があるが、メール、電話番号などのオプションの属性を含んでもよい。
LDAP略称対応
  • o:organization(組織-会社)
  • ou:organization unit(組織ユニット-部門)
  • c:countryName(国家)
  • dc:domanComponent(ドメイン名)
  • sn:suer name(本名)
  • cn:common name
  • 入門の例
    LDAPの基礎概念を理解した後、簡単な例を通してさらに理解します。
    基礎となるSpring Bootプロジェクトを作成します。(できないなら、この2つの記事を参照してください。入門1または入門2
    pom.xmlに重要な二つの依存性を導入する。
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-ldap</artifactId>
    </dependency>
    
    <dependency>
      <groupId>com.unboundid</groupId>
      <artifactId>unboundid-ldapsdk</artifactId>
      <scope>test</scope>
    </dependency>
    
    
    ここで、spring-boot-starter-data-ldapは、Spring BootパッケージのLDAP自動化構成の実現であり、LDAPサービス端末をspring-data-ldapに基づいて具体的に動作させる。
    unboundid-ldappsdkは主にここで組み込まれたLDAPサービスを使ってテスト操作を行うために設定されています。したがって、scopeはtestとして設定されています。実際のアプリケーションでは、通常は実際のLDAPサーバと接続しますので、この依存は必要ありません。
    src/test/resourceディレクトリにおいて、LDAPサービス端末の基礎データを保存するために、後のプログラムアクセス用のファイルを作成します。
    
    dn: dc=didispace,dc=com
    objectClass: top
    objectClass: domain
    
    dn: ou=people,dc=didispace,dc=com
    objectclass: top
    objectclass: organizationalUnit
    ou: people
    
    dn: uid=ben,ou=people,dc=didispace,dc=com
    objectclass: top
    objectclass: person
    objectclass: organizationalPerson
    objectclass: inetOrgPerson
    cn: didi
    sn: zhaiyongchao
    uid: didi
    userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
    
    ここで基礎ユーザーを作成しました。本名はzhaiyongchaoで、常用名didiです。後のプログラムでは、これらの情報を読み取りに来ます。もっと多くの内容はLDAPを深く勉強して理解できます。ここではあまり説明しません。
    appication.propertiesに埋め込みLDAPの構成を追加します。
    
    spring.ldap.embedded.ldif=ldap-server.ldif
    spring.ldap.embedded.base-dn=dc=didispace,dc=com
    spring-data-ldapの基礎的な使い方を使用して、LDAPにおける属性とJavaに定義されたエンティティとの関係マップと対応するRepositoryを定義します。
    
    @Data
    @Entry(base = "ou=people,dc=didispace,dc=com", objectClasses = "inetOrgPerson")
    public class Person {
    
      @Id
      private Name id;
      @DnAttribute(value = "uid", index = 3)
      private String uid;
      @Attribute(name = "cn")
      private String commonName;
      @Attribute(name = "sn")
      private String suerName;
      private String userPassword;
    }
    
    public interface PersonRepository extends CrudRepository<Person, Name> {
    }
    
    
    上記の定義の後に、PersonオブジェクトとLDAP記憶コンテンツをマッピングしました。PersonRepositoryを使用するだけで、LDAPコンテンツに対して読み書きが簡単にできます。
    作成ユニット試験用例は、すべてのユーザ情報を読み取ります。
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ApplicationTests {
    
      @Autowired
      private PersonRepository personRepository;
    
      @Test
      public void findAll() throws Exception {
        personRepository.findAll().forEach(p -> {
          System.out.println(p);
        });
      }
    }
    
    
    このテストケースを起動したら、コンソールから先のldap-server.ldifに保持されていたユーザ情報が出力されているのが見えます。
    2018-01-27 14:25:06283  WARN 73630--[           main]o.s.ldp.odm.co re.impl.Object MetaData    : The Entry class Person shound be declared final
    Person(id=uid=ben、ou=people、dc=didispace、dc=com、uid=ben、common Name=didididididididi、suerName=zhaiyongchao、userPassword=123,83,65,125,110,70,67,101,118,87,106,120,102,97,76
    ユーザを追加
    上記の入門例を通して、独立して完成すれば、LDAPをSpring Bootで動作させるための基礎的な目標が完了しました。
    Spring Dataをよく知っているなら、このサブプロジェクトも必ずRepsityの抽象を守っていると思います。したがって、上記で定義されたPersonRepositoryを使用して、簡単に動作を実現できます。例えば、下記のコードはLDAPにユーザーを追加するのに便利です。
    
    Person person = new Person();
    person.setUid("uid:1");
    person.setSuerName("AAA");
    person.setCommonName("aaa");
    person.setUserPassword("123456");
    personRepository.save(person);
    
    もっと多くの操作を実行したい場合は、spring-data-ldapのドキュメントを参照して使用することができます。
    LDAPサービスを接続する
    本論文の例では組み込みLDAPサーバが採用されていますが、実際にはこのような方法は我々の現地試験開発使用に限られています。
    Spring Bootのパッケージの下では、下記のようなパラメータを配置するだけで、上記の例を埋め込みLDAPよりも遥か端のLDAPに接続することができます。
    
    spring.ldap.urls=ldap://localhost:1235
    spring.ldap.base=dc=didispace,dc=com
    spring.ldap.username=didispace
    spring.ldap.password=123456
    本論文のコード
    以下の二つの倉庫からchapter 3-3-10ディレクトリを調べることができます。
    Github:https://github.com/dyc87112/SpringBoot-Learning/
    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。