Windows上のJenkinsでドメイン認証を使う
Active Directory環境にあるJenkinsをドメイン認証(統合Windows認証)でシングルサインオン化する方法について説明します。
ここでのシングルサインオンは、ドメインアカウントでWindowsにログオンしていて、WebブラウザでJenkinsを開くと自動的にログイン済み状態になることを指します。シングルサインオンによって利用者の負担や共用アカウントの危険性を軽減できます。
前提
下記の環境で確認しています。
- Windows Server 2008 R2
- Apache httpd 2.2.22 (64bit)
- Oracle JDK 7u6 (64bit)
- Apache Tomcat 7.0.29 (Windows service installer)
- Jenkins 1.477
- Active Directoryドメインに参加していること。
Apache httpdの設定
リバースプロキシにmod_proxy_ajpを使うと認証情報を渡せます。ポイントは以下です。
# httpd.conf LoadModule sspi_auth_module lib/modules/mod_auth_sspi.so LoadModule proxy_module lib/modules/mod_proxy.so LoadModule proxy_ajp_module lib/modules/mod_proxy_ajp.so <Location /> # Windows認証 AuthType SSPI SSPIAuth On SSPIAuthoritative On SSPIDomain DOMAIN SSPIOmitDomain On SSPIOfferBasic On Require valid-user </Location> <Location /jenkins> # リバースプロキシ ProxyPass ajp://127.0.0.1:8009/jenkins </Location> <Location /svn> # Subversionとか同居できます </Location>
Apache Tomcatの設定
Apache httpdからAJPリクエストを受け取れるようにします。ポイントは以下です。
<!-- server.xml --> <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="100" minSpareThreads="10"/> <Connector executor="tomcatThreadPool" address="127.0.0.1" URIEncoding="UTF-8" tomcatAuthentication="false" port="8009" protocol="AJP/1.3" /> <Connector executor="tomcatThreadPool" address="127.0.0.1" URIEncoding="UTF-8" port="18080" protocol="HTTP/1.1" />
Jenkinsの設定
- Jenkinsの管理
- システムの設定
- セキュリティを有効化にチェックを入れる
- サーブレットコンテナの認証を選択する
- セキュリティを有効化にチェックを入れる
- システムの設定
Apache httpdやTomcatの設定がおかしい状態で上記を適用すると、AJP経由でJenkinsにログインできなくなる可能性があります。server.xmlでHTTPコネクタも残しておくことをおすすめします。
Jenkinsの代わりに後述するJSPでも認証結果を確認できます。
カラクリについて
AJPでリバースプロキシすると認証情報がサーブレットコンテナに伝わるようになります。具体的には HttpServletRequest.html#getRemoteUser() が認証済みのユーザ名を返すようになります。
java.lang.String getRemoteUser()
Returns the login of the user making this request, if the user has been authenticated, or null if the user has not been authenticated. Whether the user name is sent with each subsequent request depends on the browser and type of authentication. Same as the value of the CGI variable REMOTE_USER.
HttpServletRequest (Java EE 6 )
このメソッドの戻り値はApache httpdの認証結果(REMOTE_USER)に依存するため、SSPI認証に限らずBasic認証などでも同じことができます。
下記のJSPでも挙動を確認できます。
<%@ page session="false" %> <html> <body> request.getRemoteUser() = <%= request.getRemoteUser() %> </body> </html>