先日マイクロソフトの寺田さんがJavaアプリケーションでActive Directory Authentication Library for Java(ADAL4J)を使うコードをgithubに公開されていましたので、私はちょっと違う方法で。
エンタープライズでJavaを使ったWebアプリケーションを開発する場合、WebLogicやWebSphere、JBossなどの商用アプリケーション・サーバ上にデプロイするケースが殆どだと思います。
このような環境下だとアプリケーションの単位でADALを使って個別に連携するよりも、アプリケーション・サーバのレイヤでAzure ADと連携させてしまった方がメリットがある場合があります。特にアプリケーションのロジックとアイデンティティ基盤を完全に分離できるので、既存アプリケーションの修正が不要となる点や同一アプリケーション・サーバ上にデプロイされているアプリケーションであれば、アプリケーション毎に設定を行う必要がない点は大きなメリットと言えます。
(ASP.NETのアプリケーションを書くときに、IISサーバをドメイン参加させて統合Windows認証が使うのか、アプリケーション単位で認証ロジックを書くのか、の違いによく似ています)
今回、WebLogicをSAML SP(Service Provider)として構成し、Azure Active Directory(Azure AD)と連携させる環境を作ってみました。
おそらくエンタープライズ屋さんであれば自宅の仮想環境にOracle DBとWebLogicの環境の一つや二つ遊んでいると思うので、ぜひ試してみてください。
早速やってみます。
1.Azure ADでアプリケーションを作成する
まずは、Azure AD側に連携するためのアプリケーションの設定を行います。Azure AD Premiumエディションを持っていれば、ギャラリーからカスタムのSAMLアプリケーションを追加できるので、今回はこちらを使っています。
アプリケーションの追加を行います。
アプリケーションが追加できたら、シングルサインオンの設定を行います。
Microsoft Azure ADのシングルサインオンを選択します。
アプリケーション設定の構成で以下を設定します。
・識別子:
後でWebLogicに設定するSP Entity IDのURIを設定します。単なる識別子なので実際にアクセスできる必要はありません。
・応答URL:
同じく後で設定するSAML AssertionのPOST先URLを設定します。こちらは実際にSAML AssertionをPOSTするので、クライアントがアクセスできるURLである必要があります。
SAML Assertionの署名に使う証明書のダウンロードを行います。この証明書をSP(WebLogic)が知っている必要がありますので、後程FederationMetadataに埋め込んでアップロードします。
WebLogicにIdP(Azure AD)の情報(エンドポイント、署名に使う証明書の情報など)を設定するためのFederationMetadataを作成します。
まずは、元となるFederationMetadata.xmlをAzureよりダウンロードします。アプリケーション一覧の画面から[エンドポイント]を開くとFederationMetadata.xmlのURLが確認できるので、ブラウザでアクセスしxmlファイルを保存します。
実は、ダウンロードしたFederationMetadata.xmlはそのままでは使えません。
理由は、以下の2点なので、修正します。
・ws-federation関係の情報が含まれている
・アプリケーション用の証明書の情報が含まれていない
先にダウンロードした証明書ファイルをメモ帳などで開き、実体部分をコピーし、FederationMetadata.xmlのX509Certificateのデータを書き換えます。
同時に、ws-fedやRoleDiscripterなど不要なエレメントをすべて削除します。結果以下のようなxmlファイルが出来上がります。
とりあえずここまででAzure AD側の設定は一旦終了です。
2.WebLogicの設定
今度はWebLogic側の設定を行います。ざっと概要を説明すると大きくは次の3点を設定する必要があります。
①セキュリティ・レルムの設定
連携するSAML IdP(ここではAzure AD)の参照設定を行います。
②サーバのSSLの有効化
Azure ADは応答先URLにHTTPSしか設定できないので、WebLogic側のSSLエンドポイントを有効化します。
③サーバのフェデレーション設定
WebLogicドメイン上のサーバをSAML SPとして設定します。
順番に設定をしていきます。
①セキュリティ・レルムの設定
WebLogicの管理コンソールで、ドメイン構造から[セキュリティ・レルム]を開き、レルム一覧から[myrealm]を開きます。
[プロバイダ]から[認証]タブを開き、認証プロバイダを追加していきます。
認証プロバイダの名前に任意の名前を、タイプに[SAML2IdentityAsserter]を設定します。
認証プロバイダを作成後、一旦管理サーバを再起動します。
その後、先ほど作成した認証プロバイダにAzure AD側の設定を入れていきます。作成した認証プロバイダを開き、[管理]タブを開き、アイデンティティ・プロバイダ・パートナーを新規作成します。この際、[新しいWebシングル・サインオンのアイデンティティ・プロバイダ・パートナー]を選択します。
作成後、先ほど作成したAzure ADのFederationMetadata.xmlを読み込ませることでほぼ自動で設定ができます。
作成が完了した後、有効化およびリダイレクトURL(このURLにマッチしたらIdPへリダイレクトする)を設定します。
今回、あとでデプロイするアプリケーションのパスが/WebApp/となるので、今回は/WebApp/*を設定しています。
ここまででセキュリティ・レルムの設定は完了です。次はサーバ設定です。
今回は管理サーバ上にアプリケーションをそのままデプロイしていますが、実環境では管理サーバとは別に被管理サーバを作成すると思うので、実環境の場合はそちらに対して設定します。
②サーバのSSLの有効化
[構成]、[サーバー]より対象のサーバを開き、SSLリスニング・ポートの有効化とポートの設定を行います。
③サーバのフェデレーション設定
次に、ようやくSAML SPとしての構成を行います。
サーバを開き、[構成]、[フェデレーション・サービス]、[SAML2.0サービス・プロバイダ]を開き、以下の設定を行います。
・有効:チェック
・アーティファクト・バインドの有効化:チェックなし
・優先バインド:POST
・デフォルトURL:アプリケーションのURL
次にSAML同じく[SAML2.0全般]タブを開き、以下の設定を行います。
・公開サイトのURL:
先にAzure ADに設定したSAML AssertionのPOST先(のパスの一部。/saml2まで)
・エンティティID:
先にAzure ADに設定したアプリケーションの識別子
※他の情報(連絡先など)は任意です。
ここまででWebLogic側も設定は終わりです。ようやくアプリケーションの作成とデプロイです。
3.アプリケーションの作成
ここではEclipseを使って単にユーザ名を表示するだけのjspを作っていますが、むしろ大切なのはweb.xmlおよびweblogic.xmlに記載するセキュリティ設定です。
index.jspのソース。
単純にgetRemoteUser()でユーザ名を取得して表示しているだけです。
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Test Application</title> </head> <body> <h1>My Test App</h1> <h4>Hello <%= request.getRemoteUser() %></h4> </body> </html>
web.xml
・security-constraintで/*(アプリケーション全体)を保護対象としています。
・auth-constraintで対象領域にはAdminおよびUserロールに属しているユーザのみがアクセスできるようにしています。
・security-roleでAdminおよびUserロールを定義しています。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>WebApp</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <security-constraint> <display-name>Protected Area</display-name> <web-resource-collection> <web-resource-name>Protected Area</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <description></description> <role-name>Admin</role-name> <role-name>User</role-name> </auth-constraint> </security-constraint> <security-role> <role-name>Admin</role-name> </security-role> <security-role> <role-name>User</role-name> </security-role> </web-app>
weblogic.xml
Security Role AssignmentでAdminロールに[nfujie]というPrincipalを割り当てています。
(このPrincipalがAzure ADから発行されるSAML AssertionのName Identifierの値と一致していればAdminロールが割り当たります)
これでアプリケーションは完成ですので、デプロイします。
今回はwarへデプロイしてWebLogicへインストールしていきます。
まず、アプリケーションのプロジェクトを右クリックしてExport、WARを選択します。
出力先のファイル名、ターゲットランタイムにWebLogicを選択してFinishをクリックします。
続いてWebLogicの管理コンソールの[デプロイメイント]より[インストール]を行います。
エクスポートしたwarファイルを指定し、次へ進めます。
これでデプロイは完了です。
4.ユーザの割り当てとName Identifier属性の設定
早速アプリケーションへアクセスしていきたいところですが、Azure ADにアプリケーション連携設定を作成した場合、対象アプリケーションにアクセスさせるユーザの割り当てを行っておく必要があります。
また、先にアプリケーション(weblogic.xml)に設定したPrincipalと同じ値がAzure ADから発行されるようにSAML Assertion上の属性のマッピングを行う必要があります。
まずは、ユーザの割り当てです。
管理ポータルよりアプリケーションを開き、[ユーザおよびグループ](Premium/Basicの場合。無償版の場合は[ユーザ])よりアクセスさせたいユーザに割り当てを行います。
次に属性の編集です。
同じく管理ポータルより[属性]を開き、SAML Assertionの編集を行います。
今回、割り当てたユーザがnfujie@pharaoh.onmicrosoft.comなのでそのままだとName Identifierにはnfujie@pharaoh.onmicrosoft.comが値として入ってしまいますが、WebLogicは単にnfujieという値を期待しているので、ドメインパートを削ってあげます。
そのためにはExtractMailPrefix()という関数を使って値の成型をする必要がありますので、nameidentifier属性を開き、以下のように設定を変更して保存を行います。
これで本当にすべて完了です。早速アクセスしてみます。
まずは、アプリケーションのURLへアクセスします。
https://wls:7002/WebApp/
するとAzure ADのログイン画面が出てくるので、先ほど割り当てたユーザでログインします。
うまく認証が完了すると、アプリケーションが開き、ユーザ名が取得できていることがわかります。
いかがでしたでしょうか?
ちなみに今回はユーザ名のみの取得でしたので、設定のみで連携させましたが、Assertion上の他の属性をWebLogic上のユーザ属性とマッピングさせるためにはカスタムの属性マッパークラスを実装することで対応が可能となります。
この辺りは別の機会にでも。
0 件のコメント:
コメントを投稿