2020/03/25

Tomcat で ActiveDirectory 認証または LDAP 認証を使う

JAAS という Java 標準の認証・認可サービスの仕様に基づいて、外部システムの認証・認可を利用することができます。
ActiveDirectory または LDAP を用いて認証・認可を行いたい場合は、Realm (レルム) として JNDIRealm を使用します。JNDI 経由でユーザ情報、ロール情報を取得して JAAS に結び付けるための Realm です。LDAP は JNDI でアクセスすることができますし、ActiveDirectory は LDAP データベースで出来ていますので、この方法で実現できます。

具体的な設定方法

server.xml の設定

server.xml の <Engine> 要素内に以下のように Realm 設定を記述します。

<Realm className="org.apache.catalina.realm.JNDIRealm"
  connectionName="CN=USERNAME,DC=example,DC=com"
  connectionPassword="PASSWORD"
  connectionURL="ldap://adserver01.example.com:389"
  alternameURL="ldap://adserver02.example.com:389"
  authentication="simple"
  userBase="DC=example,DC=com"
  userSearch="(sAMAccountName={0})"
  userSubtree="true"
  userRoleName="memberOf"
  roleBase="DC=example,DC=com"
  roleName="CN"
  roleSearch="(member={0})"
  roleSubtree="true"
  referrals="follow" />


2〜6行目は、ActiveDirectory または LDAP サーバにアクセスにアクセスするときの接続用ユーザ名とパスワード、および接続先です。冗長化されている場合、2つの接続先を指定できます。
7〜9行目は、ユーザ認証にあたってユーザをどのように特定するかの設定です。このサンプルでは ActiveDirectory を想定して、sAMAccountName にユーザ名が入っているという前提にしています。userSearch に何らかの条件を付加すれば、認証するユーザを限定することも可能でう。
10〜14行目はユーザ認可にあたり、そのユーザが持つロールを取得するための設定です。やはり ActiveDirectory 想定で書いています。userRoleName はユーザ側から見て保有するロールを取得するための属性を指定する箇所で、roleSearch はロール側から見て属するユーザを特定できるように書いています。

上記の例であれば、ActiveDirectory サーバとして adserver01.example.com と adserver02.example.com の2台に接続します。その際の接続ユーザはユーザ名「USERNAME」、パスワード「PASSWORD」で認証されます。
ユーザ情報は DC=example,DC=com から探索します。サブツリーも辿ります。ロール情報も同様に探索します。

web.xml の設定

ログイン認可を行いたい Web アプリケーションの web.xml には、以下のように利用を許すロール名を指定することで、実現できます。

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Web application authentication</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>ROLE1</role-name>
    <role-name>ROLE2</role-name>
  </auth-constraint>
</security-constraint>
<login-config>
  <!-- BASIC 認証なり FORM 認証なりの設定を書く -->
</login-config>

こうすることで、Web アプリケーションには、ROLE1, ROLE2 のいずれかのロールを持つユーザしかログインできなくなります。

用語説明

JNDI とは?

Java Naming and Directory Interface の略で、ネーミングサービス、ディレクトリサービスにアクセスするためのインターフェースを規定したものです。
Java では、JNDI を介して DNS サーバや LDAP データベースにアクセスすることができます。

ActiveDirectory とは?

Microsoft のディレクトリサービスで、ユーザ情報やコンピュータ情報を管理するものです。LDAP データベースが中核となっており、LDAP の要領でアクセスできます。

LDAP とは?

Lightweight Directory Access Protocol の略で、木構造の簡単な文字列データベースにアクセスするためのプロトコルです。