原文はこちら。
http://www.oracle.com/technetwork/articles/idm/mishra-wls-auth-2157543.html
WebLogic Serverでのログイン失敗を利用可能なデバッグフラグやログファイルを使って診断する方法をご紹介します。
Introduction
Oracle WebLogic Serverでの認証は複数の理由で失敗することがあります。失敗は通常一貫している(つまり常に発生する)場合、WebLogic Server内で認証がどのように行われているかを知っていれば、デバッグして修正することは簡単ですが、障害が偶に発生する場合はことは少々ややこしくなります。この記事では、特にLDAPのような外部システムを使うようWeblogic Serverを構成している場合、断続的な認証失敗を調べるために、どのログファイルを確認すべきか、有効化すべきデバッグオプションを探っています。また、こうした断続的な認証の失敗が原因で発生する、ユーザーアカウントのソフトロックのシナリオ、ソフトロックの確認方法、解除方法ついても説明します。
この記事は、Oracle Identity Manager(OIM)のAPIがWebLogicでの断続的な認証失敗のために断続的に失敗しはじめるという、最近のお客様の事象を背景にしています。読者のみなさんが、WebLogicセキュリティの概念と認証メカニズムをよく理解していることを前提としています。この記事で使うWebLogic Serverのバージョンは10.3.6です。
Understanding Authentication Flow in WebLogic
WebLogic Serverは、認証プロバイダを使って指定された資格情報が正しいことを証明します。WebLogicセキュリティフレームワークは、セキュリティレルムとして複数の認証プロバイダをサポートします。これらの認証プロバイダを構成(各プロバイダのJAAS制御フラグ属性)方法によっては、認証プロセスの全体的な結果に影響を与えることがあります。以下にJAAS制御フラグ属性値と、この値が認証プロセス全体をどのように制御するのかをまとめました(詳細は参考文献のセクションを参照ください)。
- REQUIRED: 認証プロバイダは常に呼び出され、ユーザは常に認証テストを通過する必要があります。認証が成功しても失敗しても、認証はプロバイダのリストの下方に進みます。
- REQUISITE: ユーザはこの認証プロバイダの認証テストを通過する必要があります。ユーザがこの認証プロバイダの認証テストを通過した場合、以降の認証プロバイダは実行されますが、(JAAS の [制御フラグ] 属性が [REQUIRED] に設定されている認証プロバイダを除いて) 失敗してもかまいません。
- SUFFICIENT: ユーザはこの認証プロバイダの認証テストを通過する必要はありません。認証が成功した場合、以降の認証プロバイダは実行されません。認証が失敗した場合、認証はプロバイダのリストの下方に進みます。
- OPTIONAL: ユーザはこの認証プロバイダの認証テストを通過することも失敗することもできます。ただし、セキュリティ レルムでコンフィグレーションされているすべての認証プロバイダで JAAS の [制御フラグ] 属性が [OPTIONAL] に設定されている場合、ユーザはコンフィグレーション済みプロバイダのいずれかの認証テストを通過する必要があります。
[REQUIRED]制御フラグの説明が示すように、このフラグを使用する認証プロバイダは認証をパスしなければなりません。もしくは、提供された資格情報が正しかった場合でも、エンドユーザ認証が失敗することがあります。これには、ネットワークの問題、認証プロバイダがやりとりする外部システム(例えばLDAP)の予期しない動作などが含まれます。
Turn On Security Debugging To See What's Going On
ログイン失敗を確認して最初にやるべきことは、WebLogic Servverのセキュリティデバッグを、リクエストが到着する可能性がある全てのサーバーでオンにすることです。リクエストが到着する可能性がある全てのサーバー、ロードバランサやt3のURL (
t3://host1:port1,host2:port2
) にある全てのサーバーに対して設定する必要があります。この設定は、サーバごとに固有です。セキュリティデバッグをオンにするには、以下の設定をする必要があります。
- [サーバー] > [サーバーインスタンス] > [デバッグ]へ移動
- WebLogic > Security > atn > DebugSecurityAtn のチェックボックスをクリック
- [有効化]ボタンをクリック
この変更はサーバーの再起動を必要としません。このフラグをONにすると、WebLogic Serverはデバッグ情報をサーバーログファイルに出力し始めます。以下はログイン成功時のログ出力例です。ここでセキュリティレルムをDefaultAuthenticatorで構成しています。
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044555> <BEA-000000>
<com.bea.common.security.internal.service.CallbackHandlerWrapper.handle got username from
callbacks[0], UserName=weblogic>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044555> <BEA-000000> <LDAP Atn Login username: weblogic>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044555> <BEA-000000> <authenticate user:weblogic>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044555> <BEA-000000> <getConnection return conn:LDAPConnection
{ ldapVersion:2 bindDN:""}>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044555> <BEA-000000> <getDNForUser search
("ou=people,ou=myrealm,dc=WLS_A",
"(&(uid=weblogic)(objectclass=person))", base DN & below)>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044556> <BEA-000000> <DN for user weblogic: uid=weblogic,
ou=people,ou=myrealm,dc=WLS_A>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044556> <BEA-000000> <returnConnection conn:LDAPConnection
{ ldapVersion:2 bindDN:""}>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044556> <BEA-000000> <authenticate user:weblogicwith DN:uid=weblogic,
ou=people,ou=myrealm,dc=WLS_A>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044556> <BEA-000000> <getConnection return conn:LDAPConnection
{ ldapVersion:2 bindDN:""}>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044556> <BEA-000000> <authentication succeeded>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044556> <BEA-000000> <returnConnection conn:LDAPConnection
{ ldapVersion:2 bindDN:""}>
####<Jan 11, 2014 8:40:44 PM IST> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '20' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <>
<1389453044556> <BEA-000000> <LDAP Atn Authenticated User weblogic>
Below is a sample output for a failed login where the security realm configured with an LDAP authenticator, and failure happened because of an LDAP connection issue:
####<Jun 5, 2013 11:07:25 PM PDT> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer>
<[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'>
<<WLS Kernel>> <> <5b0dc9d8a952b6d1:-1eccb494:13f1505b73b:-8000-000000000001c5b1>
<1370498845643> <BEA-000000>
<new LDAP connection to host SHAIMISH-LAP port 3061 use local connection is false>
.
####<Jun 5, 2013 11:07:25 PM PDT> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer>
<[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'>
<<WLS Kernel>> <> <5b0dc9d8a952b6d1:-1eccb494:13f1505b73b:-8000-000000000001c5b1>
<1370498845644> <BEA-000000>
<created new LDAP connection LDAPConnection { ldapVersion:2 bindDN:""}>
.
####<Jun 5, 2013 11:07:25 PM PDT> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer>
<[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'>
<<WLS Kernel>> <> <5b0dc9d8a952b6d1:-1eccb494:13f1505b73b:-8000-000000000001c5b1>
<1370498845673> <BEA-000000>
<connection failed netscape.ldap.LDAPException:n Server or network error (81);
Cannot contact LDAP server>
.
####<Jun 5, 2013 11:07:25 PM PDT> <Debug> <SecurityAtn> <SHAIMISH-LAP><AdminServer>
<[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'>
<<WLS Kernel>> <> <5b0dc9d8a952b6d1:-1eccb494:13f1505b73b:-8000-000000000001c5b1>
<1370498845673> <BEA-000000> <[Security:090294]could not get connection>
残念ながら、ログイン失敗の理由は常に明確というわけではありません。例えば、セキュリティレルムをLDAP authenticatorで構成している場合の断続的なログイン失敗で、次のような出力が出た場合、何が悪いのか明確ではありません。
####<Oct 7, 2013 12:44:21 PM EDT> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '246' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <>
<d99500ee4d4904e8:1daa9ea9:14193a06acc:-8000-0000000000072676> <1381164261368> <BEA-000000>
<[Security:090295]caught unexpected exception>
.................................................................................................
####<Oct 7, 2013 12:44:21 PM EDT> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '246' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <>
<d99500ee4d4904e8:1daa9ea9:14193a06acc:-8000-0000000000072676> <1381164261368> <BEA-000000>
<com.bea.common.security.internal.service.LoginModuleWrapper.commit delegated, returning false>
####<Oct 7, 2013 12:44:21 PM EDT> <Debug> <SecurityAtn> <SHAIMISH-LAP> <AdminServer> <[ACTIVE]
ExecuteThread: '246' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <>
<d99500ee4d4904e8:1daa9ea9:14193a06acc:-8000-0000000000072676> <1381164261368>
<BEA-000000> <weblogic.security.service.internal.WLSJAASLoginServiceImpl$ServiceImpl.authenticate
authenticate failed for user TESTCCOUNT>
このような場合には、標準のWebLogic LDAP authenticatorの場合、ldap_trace.logATNログファイルを確認します。このファイルはドメインディレクトリ配下にあり、LDAPとの通信で発生している情報を含んでいます。上記のシナリオでは、このログファイルから、LDAPサーバーとの接続切断の問題が明らかになりました。
Propagating failure exception to caller (applicable for callers running in same JVM)
WebLogic Serverで実行中のプログラム的にログインしているコードの場合、実際のログイン失敗の原因を標準のWebLogic Authenticatorが呼び出し元に伝播することができます。authenticatorの[プロバイダ固有]タブに、
「ログイン例外の原因を伝播」(Figure 1)というフラグがあります。これにチェックを入れると、ログイン例外の実際の原因を呼び出し元に伝播します(下図)。この情報は迅速にプログラムでのログイン失敗の原因を迅速に診断する上で有用です。
Figure 1: Propagate Cause For Login Exception
Account Soft Lockout
アカウント・ソフトロックアウトはユーザーアカウントに対するDoS攻撃を防ぐためのWebLogic Serverのメカニズムです。例えば、ユーザーアカウントログインが知られている場合、誰かが複数回の不正なログインを試行し、アカウントを管理するバックエンドシステム(例えばLDAP)でこのアカウントが永久にロックされてしまう可能性があり、その結果、実際のユーザーがアカウントロックによりログインできなくなるでしょう。このような状況を防ぐために、WebLogic Serverはアカウントのソフトロックアウト機能を提供しています。これを有効にすると、t2(時間)の間にn回の失敗ログインが発生した場合、t1(時間)の間、アカウントをWebLogic Serverランタイムでロックします。なお、t1、t2、nは設定することができます。アカウントがWebLogic Serverランタイムでソフトロックされた場合、アカウントの資格情報をバックエンドシステムに対し検証しようとしなくなります。これにより永久ロックを避けることができます。
この機能は非常に有用ではありますが、時として(具体的には断続的なログイン失敗が発生している場合)、難しい状況に陥ることがあります。アプリケーションで設定されているサービスアカウントがあり、このアカウントが頻繁に定期実行されるサービスで使われるものと仮定します。サービス開始時には、サービスアカウントの資格情報を取得し、プログラムによるログインを実行しようとします。このログインが複数回失敗した場合、WebLogic Serverランタイムはこのアカウントをソフトロックするので、このスケジュールされたサービスにとって状況は悪化します。つまり、ログイン失敗の原因が解決してもログインできない可能性がある、ということです。唯一の方法は、手動でサービスを停止し、サービスアカウントのソフトロックを解除することでしょう。
(私見ですが、アカウントライフサイクル管理の問題が発生するため、システム内にサービスの資格情報を保管すべきではありません。例えば、このアカウントのパスワードが変わると、格納されたもの全てを変更しなければならないからです。そうしないと、ログイン失敗の原因になります。のういう場合にはIDアサーションを使うべきでしょう。この場合はアカウントのユーザーIDのみがあればいいのです。WebLogic ServerでOPSSを使ってIDアサーションを実現する方法に関する情報は、参考文献のセクションをご覧下さい)。
以下のセクションでは、アカウント・ソフトロックアウトをWebLogic Serverで構成している状況と、UserLockoutManagerを使って、アカウント・ソフトロックアウトを解除する方法を説明します。
WebLogic Soft Lockout Configuration and Manager
ソフトロックアウトの設定情報は、[セキュリティ・レルム
]>[レルム名] > [ユーザーのロックアウト]で確認できます(下図)。
Figure 2: Soft Lockout Configuration
特定のWebLogic Serverインスタンスでの無効なログインに関する統計情報は、[サーバー] > [サーバー名] > [監視] > [セキュリティ] から確認できます(下図)。
Figure 3: Invalid Login Stats
手動でアカウントのソフトロックアウトを解除するために、WebLogic Serverでは
UserLockoutManagerというMBeanを提供しています。このMBeanには
isLockedOutと
clearLockoutというメソッドがあります。これらのメソッドは、パラメータとして、ユーザのログインIDを取ります。アカウントのソフトロックアウトを削除するには、
clearLockoutメソッドを呼び出します。
isLockedOutメソッドを呼び出して、当該アカウントがソフトロックされているかどうかを確認することができます。
Figure 4: Account Soft Lock Status
Conclusion
この記事では、利用可能なデバッグフラグやログファイルを使って、WebLogic Serverでのログイン失敗を診断する方法を説明してきました。パフォーマンスの理由で、このデバックログ出力を有効にしたままにしないでください。認証の問題を診断したら、このフラグをOffにしてください。また、この記事では、断続的なログインの失敗により、WebLogic Serverでどのようにアカウントがソフトロックされるのか、そしてUserLockoutManagerというMBeanを使って、このソフトロックを取り除く方法もご紹介しました。
参考資料
- 認証プロバイダ(Authentication Providers)
(日本語)http://docs.oracle.com/cd/E51625_01/web.1111/b61623/atn.htm
(英語)http://docs.oracle.com/cd/E23943_01/web.1111/e13718/atn.htm
- 認証プロバイダの構成(Configuring Authentication Providers)
(日本語)http://docs.oracle.com/cd/E51625_01/web.1111/b61617/atn.htm
(英語)http://docs.oracle.com/cd/E29542_01/web.1111/e13707/atn.htm
- Programmatic Identity Assertion with Oracle Platform Security Services (OPSS)
(英語)http://www.oracle.com/technetwork/articles/idm/mishra-id-opss-2088117.html
Authenticator関連の問題のトリアージの手助けをしてくれたShaun Peiに感謝いたします。
著者について
Shailesh K. Mishrah はOracle Identity Managerチームの一員で、Indian Institute of Technology (Banaras Hindu University)の工学士を取得しており、自由な時間を使ってミドルウェアのパフォーマンスとセキュリティを調べています。