JavaからActive Directoryのアクセス制御エントリを取得 / JavaからLDAP/Active Directoryサーバ認証

木曜日 , 28, 10月 2021 Leave a comment

JavaからActive Directory上の共有フォルダやファイルのアクセス制御エントリ(ACE)を取得するサンプルプログラムです。
最初はLDAP経由で取得できないか試みたのですがWindows ServerのACEは標準的なLDAPライブラリでは取得できないようなのでこの機能に対応したjCIFS NGを使って取得しています。
おまけとして単純なLDAP/Active Directory認証を行うサンプルプログラムも公開します。

スクリーンショット 2021-10-28 155434

このプログラムでできること

このプログラムは、ソース中に記載されたユーザ名とパスワードを使って、指定URLへのアクセスを試みて、アクセス制御エントリ情報を取得し画面に表示します。

プログラムの実行にあたっては、jCIFS NG ( https://github.com/AgNO3/jcifs-ng )とjcifs-ngが必要とするライブラリがクラスパス上に存在する必要があります。

ソースコード

アクセス制御エントリ(ACE)の取得するサンプルプログラム

import java.util.Properties;

import jcifs.config.PropertyConfiguration;
import jcifs.context.BaseContext;
import jcifs.smb.NtlmPasswordAuthenticator;
import jcifs.smb.SmbAuthException;
import jcifs.smb.SmbException;
import jcifs.smb.SmbFile;

/**
 * 	Windows Server / Samba 上のフォルダ・ファイルのアクセス制御エントリ(ACE)を
 * 	取得し表示するプログラム。<br>
 * 
 * 	実行には jcifs-ng (https://github.com/AgNO3/jcifs-ng) と依存するライブラ
 * 	リのインストールが必要です。
 * This software is distributed under the license of NYSL.
* http://www.kmonos.net/nysl/ * */ public class AceList { /** SMBのユーザ名 */ private static final String SMB_USER = "《Active Directory/Sambaのユーザ名》"; /** SMBのパスワード */ private static final String SMB_PASSWORD = "《Active Directory/Sambaのパスワード》"; /** * アクセス制御エントリを得たいURL<br> * * 記述のしかたは下記URLを参照 * https://javadoc.io/static/org.codelibs/jcifs/2.1.3/jcifs/smb/SmbFile.html */ private static final String[] SMB_URL_LIST = new String[] { "smb://《SMBサーバのアドレス》/《共有フォルダ名》/", "smb://《SMBサーバのアドレス》/共有フォルダ/", "smb://《SMBサーバのアドレス》/共有フォルダ/特定のファイル_1.txt", }; /** * * @param args */ public static void main(String[] args) { try { // サポートするSMBの範囲 // 詳細は下記URL参照 // https://github.com/AgNO3/jcifs-ng/blob/master/src/main/java/jcifs/DialectVersion.java var props = new Properties(); props.setProperty("jcifs.smb.client.minVersion", "SMB202"); props.setProperty("jcifs.smb.client.maxVersion", "SMB311"); var baseContext = new BaseContext(new PropertyConfiguration(props)); var authenticator = new NtlmPasswordAuthenticator(SMB_USER, SMB_PASSWORD); var cifsContext = baseContext.withCredentials(authenticator); for (var url : SMB_URL_LIST) { // リソースを開く System.out.println("url=" + url); try (var smb = new SmbFile(url, cifsContext)) { // ACEを取得し表示 var aces = smb.getSecurity(); for (var ace : aces) { System.out.println("\t" + ace); } smb.close(); } catch (SmbException e) { // 指定ユーザの権限不足、指定リソースがないときなどに発生する例外 e.printStackTrace(); } System.out.println("\n"); } } catch (SmbAuthException e) { // AD認証エラーやアクセス拒否などの例外 e.printStackTrace(); } catch (Exception e) { // その他の例外 e.printStackTrace(); } } }

(おまけ) LDAP/Active Directoryサーバを使い認証を行うサンプルプログラム

import java.text.MessageFormat;
import java.util.Hashtable;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;

/**
 * LDAP/Active Directory認証を行うサンプルプログラム
 * 
 *
 *	This software is distributed under the license of NYSL.
 *	http://www.kmonos.net/nysl/
 */
public class LdapAuthTest {

	/** 認証に使うLDAP/Active Directoryサーバの名前またはIPアドレス */
	private static final String LDAP_HOST = "《LDAP/ADサーバ》";

	/** LDAP/Active Directoryへのログインに使用するユーザ名 */
	private static final String AD_USERNAME = "《LDAPユーザ名》";
	/** LDAP/Active Directoryへのログインに使用するパスワード */
	private static final String AD_PASSWORD = "《LDAPパスワード》";

	/**
	 * メイン
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		if (auth(AD_USERNAME, AD_PASSWORD)) {
			System.out.println("ログイン成功");
		} else {
			System.out.println("ログイン失敗");
		}
	}

	/**
	 * LDAP認証を試みる <br>
	 * 
	 * @param username ユーザ名
	 * @param password パスワード(平文)
	 * @return trueの場合、ログイン成功。falseの場合、失敗。
	 */
	public static boolean auth(String username, String password) {

		Hashtable<String, String> map = new Hashtable<String, String>();

		map.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		map.put(Context.PROVIDER_URL, MessageFormat.format("ldap://{0}:389", LDAP_HOST));
		map.put(Context.SECURITY_AUTHENTICATION, "simple");

		map.put(Context.SECURITY_PRINCIPAL, username);
		map.put(Context.SECURITY_CREDENTIALS, password);

		try {

			InitialLdapContext ctx = new InitialLdapContext(map, null);
			ctx.close();

			return true;

		} catch (AuthenticationException e) {
			e.printStackTrace();
			return false;

		} catch (NamingException e) {
			e.printStackTrace();
			return false;
		}
	}

}

Please give us your valuable comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください