
CVE-2016-4468
UAAはマルチテナントID管理サービスであり、Cloud Foundryで使用されますが、スタンドアロンのOAuth2サーバーとしても利用可能です。主な役割はOAuth2プロバイダーであり、Cloud Foundryユーザーに代わって動作するクライアントアプリケーションが使用するトークンを発行します。また、Cloud Foundryの認証情報を使用してユーザーを認証したり、それらの認証情報(または他のもの)を使用してSSOサービスとして機能することもできます。ユーザーアカウント管理およびOAuth2クライアント登録のためのエンドポイントに加え、さまざまな管理機能も備えています。
必要条件:
これが動作すれば準備は完了です:
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ ./gradlew run
すべてのアプリは同じポート(8080)上で動作し、/uaa, /app, /api としてアクセスできます。
UAAはuaa.logというファイルにログを出力します。次のコマンドで見つけることができます:-
$ sudo find / -name uaa.log
以下のような場所に見つかるはずです:-
/private/var/folders/7v/518b18d97_3f4c8fzxphy6f8zcm51c/T/cargo/conf/logs/
アプリをビルドしてCloud Foundryにプッシュすることもできます。例えば、推奨する方法はマニフェストファイルを使用することですが、すべてをコマンドラインで行うこともできます。
$ ./gradlew :cloudfoundry-identity-uaa:war
$ cf push myuaa --no-start -m 512M -p uaa/build/libs/cloudfoundry-identity-uaa-2.3.2-SNAPSHOT.war
$ cf set-env myuaa SPRING_PROFILES_ACTIVE default,hsqldb
$ cf set-env myuaa UAA_URL http://myuaa.<domain>
$ cf set-env myuaa LOGIN_URL http://myuaa.<domain>
$ cf set-env myuaa JBP_CONFIG_SPRING_AUTO_RECONFIGURATION '[enabled: false]'
$ cf set-env myuaa JBP_CONFIG_TOMCAT '{tomcat: { version: 7.0.+ }}'
$ cf start myuaa
上記の手順で、次の項目を置き換えてください:
myuaa を一意のアプリケーション名に2.3.2-SNAPSHOT をビルドの適切なバージョンラベルに<domain> はアプリのドメインです。将来はシステム環境から解析される予定です。まず、上記のようにUAAサーバーを実行します:
$ ./gradlew run
次に、別のターミナルを開き、プロジェクトのベースディレクトリから、ログインエンドポイントにシステムについて問い合わせます:
$ curl -H "Accept: application/json" localhost:8080/uaa/login
{
"timestamp":"2012-03-28T18:25:49+0100",
"commit_id":"111274e",
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
次に、UAA Ruby gemを使用してログインを試すことができます。Ruby 1.9が必要です。その後、
$ gem install cf-uaac
$ uaac target http://localhost:8080/uaa
$ uaac token get marissa koala
(またはユーザー名/パスワードを省略してプロンプトを受け取ります)。
これにより、OAuth2 implicit grantを使用してサーバーからアクセストークンを認証・取得します。これは、CFのようなクライアントが使用するアプローチと同様です。トークンは ~/.uaac.yml に保存されるので、そのファイルからアクセストークンを取得して cf ターゲットに使用するか、上記のログインコマンドラインで --verbose を使用してコンソールに出力されたトークンを確認してください。
次に、リソースサーバーとしてログインし、トークンの詳細を取得できます:
$ uaac target http://localhost:8080/uaa
$ uaac token decode
標準出力に自分のユーザー名と元のトークン付与のクライアントIDが表示されます。例:
exp: 1355348409
user_name: marissa
scope: cloud_controller.read openid password.write scim.userids tokens.read tokens.write
email: [email protected]
aud: scim tokens openid cloud_controller password
jti: ea2fac72-3f51-4c8f-a7a6-5ffc117af542
user_id: ba14fea0-9d87-4f0c-b59e-32aaa8eb1434
client_id: cf
$ ./gradlew -Dspring.profiles.active=default,mysql run
このコマンドは、デフォルト設定でアクセス可能なMySQLデータベースがあることを前提とし、以下のJDBC設定に応答します。
driver = 'org.mariadb.jdbc.Driver'
url = 'jdbc:mysql://localhost:3306/uaa'
user = 'root'
password = 'changeme'
schemas = ['uaa']
同様に、次のコマンドを実行すると
$ ./gradlew -Dspring.profiles.active=default,postgresql run
次の設定が使用されます:
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql:uaa'
user = 'root'
password = 'changeme'
これらの設定は、Gradle統合のために2か所に重複しています。Spring XML設定ファイルにデフォルトとして定義されており、メインのbuild.gradleファイルにも定義されています。Gradleビルドファイルにこれらがある理由は、Gradleが常にUAAアプリケーションを起動する前にflywayCleanタスクを実行するためです。データベースをクリーンアップしたくない場合は、コマンドラインで変数 -Dflyway.clean=false を定義できます。これにより、gradleスクリプト内のflywayCleanタスクが無効になります。flywayCleanを無効にする別の方法は、コマンドラインでSpringプロファイルを指定せず、uaa.ymlおよびlogin.ymlファイルでプロファイルを設定することです。
同じコマンドライン例はrun.pivotal.ioで実行されているUAAでも動作するはずです(クライアントシークレットがないためトークンデコード部分は除く)。この場合、ローカルのUAAサーバーを実行する必要はないため、外部のログインエンドポイントにシステムについて問い合わせるだけです:
$ curl -H "Accept: application/json" login.run.pivotal.io
{
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
その後、UAA Ruby gemを使用してログインを試すことができます。Ruby 1.9が必要です。その後、
$ gem install cf-uaac
$ uaac target uaa.run.pivotal.io
$ uaac token get [yourusername] [yourpassword]
(またはユーザー名/パスワードを省略してプロンプトを受け取ります)。
これにより、OAuth2 implicit grantを使用してサーバーからアクセストークンを認証・取得します。これはCFのようなクライアントが使用するものと同じです。
次のコマンドで統合テストを実行できます
$ ./gradlew integrationTest
統合テストはローカルのApache Tomcatインスタンスで実行されているUAAサーバーに対して実行されるため、例えばサービスURLはデフォルトで http://localhost:8080/uaa に設定されます。
CLOUD_FOUNDRY_CONFIG_PATH を指定して、URLを変更できる uaa.yml を読み込み、(必要に応じて)サーバー実行のコンテキストルートを設定できます(詳細は以下参照)。
実行時パラメータを変更するには、uaa.yml を提供できます。例:
$ cat > /tmp/config/uaa.yml
uaa:
host: uaa.appcloud21.dev.mozycloud
test:
username: [email protected] # defaults to [email protected]
password: changeme
email: [email protected]
次に、uaa/uaa ディレクトリから
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp/config ./gradlew test
Webアプリは起動時に以下の場所からYamlコンテンツを探します(後のエントリが前のものを上書きします)。
classpath:uaa.yml
file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
file:${UAA_CONFIG_FILE}
${UAA_CONFIG_URL}
System.getEnv('UAA_CONFIG_YAML') -> 環境変数。設定されている場合は有効なYamlを含む必要があります。
例えば、UAAをCloud Foundryアプリケーションとしてデプロイするには、以下のようなアプリケーションマニフェストを提供できます。
---
applications:
- name: standalone-uaa-cf-war
memory: 512M
instances: 1
host: standalone-uaa
path: cloudfoundry-identity-uaa-3.0.0-SNAPSHOT.war
env:
JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '[enabled: false]'
JBP_CONFIG_TOMCAT: '{tomcat: { version: 7.0.+ }}'
SPRING_PROFILES_ACTIVE: hsqldb,default
UAA_CONFIG_YAML: |
uaa.url: http://standalone-uaa.cfapps.io
login.url: http://standalone-uaa.cfapps.io
smtp:
host: mail.server.host
port: 3535
または、代替として、set-envコマンドを使用して環境変数にYAML設定を文字列として設定します。
cf set-env sample-uaa-cf-war UAA_CONFIG_YAML '{ uaa.url: http://standalone-uaa.myapp.com, login.url: http://standalone-uaa.myapp.com, smtp: { host: mail.server.host, port: 3535 } }'
さらに、UAAによって読み取られる単純型プロパティは、システム環境変数自体として完全に展開して読み取ることもできます。uaa.url が UAA_URL という環境変数に変換される方法に注目してください。
---
applications:
- name: standalone-uaa-cf-war
memory: 512M
instances: 1
host: standalone-uaa
path: cloudfoundry-identity-uaa-3.0.0-SNAPSHOT.war
env:
JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '[enabled: false]'
JBP_CONFIG_TOMCAT: '{tomcat: { version: 7.0.+ }}'
SPRING_PROFILES_ACTIVE: hsqldb,default
UAA_URL: http://standalone-uaa.cfapps.io
LOGIN_URL: http://standalone-uaa.cfapps.io
UAA_CONFIG_YAML: |
smtp:
host: mail.server.host
port: 3535