RailsからLDAPSでActiveDirectryのユーザパスワード変更


エンタメ系企業の社内もろもろを担当しているakibinです。

最近、我が息子(4)はKroiというバンドのbalmy lifeという曲にハマってます。かけてくれとせがむせがむ。今度彼のお気に入りプレイリストでも作ってあげよ。

やったこと

ドメイン参加していない状況で、ActiveDirectryのユーザパスワードをユーザが変更できるアプリをRailsで作成する必要がありました。
基本ドメイン参加してればパスワード変更できるので、あんまりないケースなのかと思いますが、そのあまりないケースが発生したので…

今回はRubyからLDAPでディレクトリサービスを操作できるnet-ldapというgemを使用しました。

ADのパスワード変更するための条件

なにやら色々調べていたら、ADの場合はOpen-LDAPとかと違って、LDAPで色々操作するには条件があるようで。
https://blog.cles.jp/item/10893

  • サーバへの接続は LDAPS でないといけない
  • bind に使うユーザーは Administrator でないといけない(Domain Users では自分のパスワードの更新も不可)
  • アップデートにはダブルクオートで囲った平文を UTF-16LE でエンコードする必要がある
  • アップデートに使うパスワードはAD のパスワードポリシーに適合していないといけない

全体的にごもっともな内容なのですが、bind に使うユーザーは Administrator でないといけないだけは解せない。
コードにAdministratorのID/PWを記述したくないなとMicrosoft TeckNetで質問してみたところ、そんなことはありませんでした。該当ユーザにパスワードリセット権限をつければOKです。

事前準備

ADの該当ユーザにパスワードリセット権限を付ける

Microsoft TeckNetで質問してみた を参照して事前にADで設定してください。

net-ldapのインストール

Gemfileにnet-ldapを追記してインストールします。

Gemfile
gem 'net-ldap'
bundle install

ADのサーバ証明書をRailsのサーバ環境にインストール

LDAPSをするためにADのサーバ証明書をRailsが構築されているサーバにインストールしてください。

そしてコードはこんな感じ

  • ADのドメイン
    hoge.co.jp
  • ADでユーザが作成されているOU 
    users
require "net/ldap"

@user = user_id #該当ユーザのID
@oldPassword = old_password #該当ユーザの現在のパスワード
@newPassword = new_password #該当ユーザの新しいパスワード

@ldap = Net::LDAP.new :host => "hoge.co.jp",
                          :port => 636, # LDAPSで接続
                          :encryption => :simple_tls,
                          :auth => {
                            :method => :simple,
                            :username => "cn=#{@user},ou=users,dc=hoge,dc=co,dc=jp",
                            :password => @oldPassword
                          }

# ADへ接続(bind)
@ldap.bind

dn = "cn=#{@user},ou=users,dc=hoge,dc=co,dc=jp",

# UTF-16LEでエンコード
def encode_passwd(string)
  newstring = ""
  string = "\"" + string + "\""
  string.split("").each do |c|
      newstring = "#{newstring}#{c}\000"
    end
  return newstring
end

newUniPW = encode_passwd(@newPassword)

# ユーザに行う操作を指定:パスワード(unicodePwd)をReplace
opts = [
  [ :replace, :unicodePwd, newUniPW ]
]

# 更新を実行
@ldap.modify(:dn => dn, :operations => opts)

このコードを使って、ADユーザのパスワード変更できました!

こちらもチェックお願いします!

Twitterアカウント
Youtubeチャンネル