この章では、WebアプリケーションでOracle ADF Securityを使用して、Oracle Application Serverで認証と認可を処理する方法について説明します。コンテナ管理のセキュリティに厳格に従う場合にOracle ADF Securityを省略する方法についても説明します。
この章の内容は次のとおりです。
Oracle ADF Securityは、Webアプリケーションのセキュリティを提供します。Oracle ADF Securityは、認証と認可のためのOracle Application Server Java Authentication and Authorization(JAAS)Providerを実装する交換可能アーキテクチャに基づいて実装されます。
認証を使用すると、現在のユーザーを特定できます。Oracle ADF Securityは、各種リソース・プロバイダ内のデータに対してユーザーを認証できます。
認可を使用すると、リソースへのアクセスを試みるユーザーに基づいてアプリケーションまたはアプリケーションの一部(リソース)へのアクセスを制限できます。Oracle ADF Securityでは、ADF Modelレイヤー・オブジェクトで認可を設定できます。
まず、リソース・プロバイダを使用するようにアプリケーションを構成する必要があります。ログインとパスワードの認証に使用されるユーザー・データは、データベースやLDAPディレクトリなどのリソース・プロバイダ内に格納されます。jazn.xmlファイルを編集して、OracleAS JAAS Providerのアイデンティティ管理プロバイダを選択します。jazn.xmlファイルの編集については、次の項をお読みください。
次に、Oracle ADF Securityを使用するようにアプリケーションのコンテナを構成します。これで、認証と認可にOracle ADF Securityを使用できるようになります。Oracle ADF Securityを使用せずに、コンテナ管理のセキュリティを使用することもできます。次の各項では、認証を構成し、ログイン・ページとログアウト・ページを作成する方法について説明しています。
リソースを特定のユーザーに指定する場合は、Oracle ADF Modelレイヤーを使用して認可を有効にできます。ADFによる認可を使用しない場合も、ADFによる認証を使用できます。標準のJ2EEによる認可とOracle ADF Modelレイヤーを統合して、リソースを制限することもできます。SRDemoアプリケーションでは、後者のアプローチを使用します。次の項を参照し、認可を実装するための両方のアプローチを理解してください。
|
注意: OC4Jのセキュリティ機能の詳細は、Oracle Application Serverドキュメント・ライブラリの『Oracle Containers for J2EEセキュリティ・ガイド』を参照してください。たとえば、「標準セキュリティの概要」では、JAASセキュリティ・モデルの概要を説明しています。 |
軽量のXMLリソース・プロバイダ(system-jazn-data.xml)またはOracle Internet DirectoryからJAZNレルムを使用する場合は、jazn.xmlファイルを編集して、これらのプロバイダの1つを選択する必要があります。
注意: 別のJAAS準拠セキュリティ・プロバイダを使用している場合は、セキュリティ・プロバイダのマニュアルを参照してください。
軽量XMLリソース・プロバイダ(system-jazn-data.xml)またはOracle Internet Directory(LDAPプロバイダ)からJAZNレルムを使用するには、アプリケーションでどちらのプロバイダを使用するかを指定する必要があります。
リソース・プロバイダを指定するには、次のディレクトリにあるjazn.xmlのプロバイダ環境ディスクリプタを編集します。
JDeveloperの埋込みOC4Jの場合:
<JDEV_HOME>/jdev/system/oracle.j2ee.10.1.3/embedded-oc4j/configディレクトリ
JDeveloperのスタンドアロンOC4Jの場合:
<JDEV_HOME>/j2ee/home/configディレクトリ
Oracle Application Serverの場合:
<OC4J_HOME>/j2ee/<instance_name>/configディレクトリ
XMLベースのプロバイダで使用する場合は、LDAPの環境ディスクリプタをコメント・アウトします。
<jazn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://xmlns.oracle.com/oracleas/schema/jazn-10_0.xsd"
schema-major-version="10"
schema-minor-version="0"
provider="XML"
location="./system-jazn-data.xml"
default-realm="jazn.com"
/>
<!--
<jazn
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://xmlns.oracle.com/oracleas/schema/jazn-10_0.xsd"
schema-major-version="10"
schema-minor-version="0"
provider="LDAP"
location="ldap://myoid.us.oracle.com:389"
/>
-->
LDAPプロバイダを使用する場合は、XMLの環境ディスクリプタをコメント・アウトします。
<!--
<jazn
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://xmlns.oracle.com/oracleas/schema/jazn-10_0.xsd"
schema-major-version="10"
schema-minor-version="0"
provider="XML"
location="./system-jazn-data.xml"
default-realm="jazn.com"
/>
-->
<jazn
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"http://xmlns.oracle.com/oracleas/schema/jazn-10_0.xsd"
schema-major-version="10"
schema-minor-version="0"
provider="LDAP"
location="ldap://myoid.us.oracle.com:389"
/>
Oracle ADF SecurityではOracleAS JAASを使用するため、LoginContextに基づいて基本的な認証を行います。LoginContextでは、実際の認証を処理する交換可能なコード・ビットであるログイン・モジュールを使用します。Oracle ADF Securityでは、標準的なユーザー名とパスワードによる認証に、OracleAS JAAS ProviderのRealmLoginModuleログイン・モジュールも使用します。
Oracle ADF Securityは、指定されたリソース・プロバイダに対してユーザーを認証できます。データベースやLDAPディレクトリなどのリソース・プロバイダには、ログインとパスワードを認証するためのデータが含まれています。
具体的には、Oracle ADF Securityは、Oracle Single Sign-OnとOracle Internet Directory(OID)を使用した認証をサポートしています。スケーラビリティと高い管理機能が必要な本番環境では、OID(LDAPベースのプロバイダ)を使用して、アイデンティティ管理を提供する必要があります。この場合、Oracle Containers for J2EEに付属のLDAP管理ツールを使用してユーザーを管理する必要があります。
OID使用の詳細は、Oracle Application Serverドキュメント・ライブラリの『Oracle Identity Management委任管理ガイド』を参照してください。
さらに、JDeveloperには、小規模アプリケーションや開発およびテストに使用できるXMLベースのリソース・プロバイダ(system-jazn-data.xml)も付属しています。このプロバイダには、ユーザー、ロール、権限およびログイン・モジュールの構成が含まれています。
多くのWebベース・アプリケーションには、リクエストの発信者に関する情報が必要な、サイトの「保護された」領域へのリンクがある場合があります。つまり、リンク先の領域へは、認証されたユーザーのみがアクセスできます。これは、adfAuthenticationサーブレットを使用するか、OC4Jが提供するJ2EEコンテナ管理の認証のみを使用しADFを使用しないで、動的に実現できます。どちらの方法でも、コンテナにセキュリティ制約を構成して、認証されていないセッションによるサーバーへのアクセスを防ぎます。
|
注意: SRDemoアプリケーションでは、現在ADF ModelレイヤーでのOracle ADF Securityのデモを行えません。SRDemoアプリケーションでの認証の処理方法については、30.3.1項「J2EEコンテナ管理の認証を有効にする方法」を参照してください。 |
ユーザーが認証されると、アプリケーションはそのユーザーが認可制約で定義されたリソースにアクセスする権限を持っているかどうかを判断できます。この制約とアプリケーションで認識されるユーザーまたはロールは、web.xmlファイルで設定します。
たとえば、SRDemoアプリケーションでは、3つのロールを使用して、だれがどのような機能を実行するアクセス権を持つかを指定しています。各ユーザーを、user、technicianまたはmanagerの3つのロールのいずれかに分類する必要があります。3つの基準はすべて、Oracle Application Serverが提供するコンテナ管理のフォームベース認証を使用して実装されます。
アプリケーションに、データ・ストアにアクセスするユーザーの認証が必要なページが含まれている場合、web.xml構成ファイルで次の宣言をする必要があります。
<security-role>では、セキュリティ・コンテキストでの有効なロールを定義します。
<login-config>では、フォームベースまたはHTTPSなど、認証のプロトコルを定義します。
<security-constraint>では、認可されたユーザーまたはロールのみがアクセスできるリソースをURLパターンとHTTPメソッドで定義します。
<servlet>では、認証を提供するサーブレットを定義します。
<servlet-mapping>では、サーブレットをURLパターンにマップします。
<filter>では、認証リクエストの内容の変換に使用するフィルタを定義します。
<filter-mapping>では、フィルタをアプリケーションが使用するファイル拡張子にマップします。ADFバインディング・フィルタの詳細は、「ADFバインディング・フィルタの構成」を参照してください。
|
注意: JSFページにADF Facesコンポーネントを初めて挿入したとき、JDeveloperはweb.xmlファイルを更新し、ADF Facesサーブレット・フィルタおよびADF Facesリソース・サーブレットを定義します。これらのサーブレット設定の詳細は、「ADF Facesコンポーネントの初回挿入時に発生する処理」を参照してください。 |
アプリケーションが認識するユーザー・グループの論理名は、web.xmlファイル内で定義するセキュリティ・ロールによって指定します。セキュリティ制約を作成して、認証されたユーザーが認可されたロールに属しているかどうかに基づいて特定のWebページに対するアクセスを制限します。
J2EEコンテナ管理のセキュリティ用にセキュリティ・ロールを指定する方法:
ナビゲータでJSPプロジェクトを展開し、web.xmlファイルを右クリックして「プロパティ」を選択します。web.xmlファイルは、プロジェクトのWEB-INFフォルダにあります。
セキュリティ・ロール定義を追加するには、「Webアプリケーション・デプロイメント・ディスクリプタ」エディタの左パネルの「セキュリティ・ロール」を選択し、「追加」をクリックします。
ここに入力したロールは、データ・ストアからのロールと一致している必要があります。たとえば、XMLベースのプロバイダ(system-jazn-data.xmlを使用して定義)を使用している場合は、認証が必要な定義済の<roles>の<name>の値を入力します。さらに、セキュリティ・ロール・マッピングを使用するようにOC4Jを構成する場合は、ロール名はorion-web.xml構成ファイルの<security-role-mapping>要素で定義されたロールとも一致している必要があります。
すべての変更を保存し、後述のログイン構成の作成に進みます。
図30-1に示すweb.xmlエディタには、セキュリティ・ロールの定義が表示されています。SRDemoアプリケーションでは、3つのセキュリティ・ロールを定義します。
ログイン構成を構成する前に、ログインWebページとオプションのログイン・エラー・ページを作成しておく必要があります。詳細は、30.5項「ログイン・ページの作成」を参照してください。
J2EEコンテナ管理のセキュリティ用にログイン構成を作成する方法:
ナビゲータでJSPプロジェクトを展開し、web.xmlファイルを右クリックして「プロパティ」を選択します。web.xmlファイルは、プロジェクトのWEB-INFフォルダにあります。
ログイン構成を作成するには、エディタの左パネルで「ログイン構成」を選択します。たとえば、フォームベースの認証を使用するには、「フォームベース認証」を選択し、login.jspxやloginerror.jspxなど、ログイン・ページとログイン・エラー・ページのレンダリングに使用するファイルの名前を入力します。詳細は、30.5.1項「ログイン・ページとエラー・ページの関連付け」を参照してください。
すべての変更を保存し、「Webアプリケーション・デプロイメント・ディスクリプタ」エディタを閉じます。
図30-2に示すweb.xmlエディタには、ログイン構成の定義が表示されています。
J2EEコンテナ管理のセキュリティ用にセキュリティ制約を作成する方法:
ナビゲータでJSPプロジェクトを展開し、web.xmlファイルを右クリックして「プロパティ」を選択します。web.xmlファイルは、プロジェクトのWEB-INFフォルダにあります。
セキュリティ制約の定義を追加するには、エディタの左側で「セキュリティ制約」を選択し、パネルの下部で「新規」をクリックします。
新しいWebリソースを追加するには、「制約」ページで「追加」をクリックします。
ヒント: セキュリティ制約はURLとして指定するため、Webリソース名は、アプリケーションのデータベース接続名に基づいて指定できます。たとえば、データベース接続がMyConnectionの場合、Webリソース名にjdbc/MyConnectionと入力できます。
クライアント・リクエストのURLパターンを指定するには、指定したWebリソース名をクリックし、「URLパターン」を選択して「追加」をクリックします。Webアプリケーション・フォルダを基準にトップ・レベルにあるJSPログイン・ページを参照するには、スラッシュ(/)を入力します。
認可されたセキュリティ・ロールを指定するには、「認可」タブを選択します。認証を必要とするセキュリティ・ロールを選択します。手順2で設定したロールを選択できます。
トランスポート保証を指定するには、「ユーザー・データ」タブを選択します。使用する保証のタイプを選択します。
すべての変更を保存し、「Webアプリケーション・デプロイメント・ディスクリプタ」エディタを閉じます。
図30-3に示すweb.xmlエディタには、セキュリティ制約の定義が表示されています。
例30-1に、J2EEコンテナ管理のセキュリティの構成を終えるとweb.xmlファイルに含まれる定義のサンプルを示します。
例30-1 SRDemoアプリケーションのweb.xmlファイルで有効に設定されたJ2EEセキュリティ
<security-constraint>
<web-resource-collection>
<web-resource-name>ALL Manager</web-resource-name>
<url-pattern>faces/app/management/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>AllStaff</web-resource-name>
<url-pattern>faces/app/staff/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>technician</role-name>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>SRDemo Sample</web-resource-name>
<url-pattern>faces/app/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
<role-name>technician</role-name>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>infrastructure/SRLogin.jspx</form-login-page>
<form-error-page>infrastructure/SRLogin.jspx</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description>Customers of ACME corp</description>
<role-name>user</role-name>
</security-role>
<security-role>
<description>Employees of ACME corp</description>
<role-name>technician</role-name>
</security-role>
<security-role>
<description>The boss</description>
<role-name>manager</role-name>
</security-role>
ユーザーが保護されたページへのリンクをクリックし、そのユーザーが認証されていない(認証済のユーザー・プリンシパルが現在SecurityContextにない)場合、OC4Jのセキュリティ・サーブレットがコールされ、Webコンテナによってデプロイメント・ディスクリプタの<form-login-config>要素に定義されたログイン・ページが起動されます。
ユーザーがユーザー名とパスワードを送信すると、そのデータはユーザー情報が格納されているリソース・プロバイダのデータと比較され、一致した場合、リクエストの送信者(ユーザー)は認証されます。ユーザー名がSecurityContextに格納されます。ここには、認可権限を判断するために他のセキュリティ関連情報(ユーザーが属するグループなど)を取得するときにアクセスできます。
web.xmlデプロイメント・ディスクリプタでは、アプリケーションの認証済ユーザーが利用可能なリソースを指定する<security-constraints>による宣言的なセキュリティをサポートしています。ユーザーがWebページへのアクセスを許可されるかどうかは、<auth_constraint>要素で指定されているロール内の該当するメンバーシップによって異なります。アプリケーションは、サーブレット・メソッドisUserInRole()をコールして、与えられているセキュリティ・ロール内に個々のユーザーが存在しているかどうかを調べます。<security-role>要素は、system-jazn-data.xmlファイル内でJAZNレルムによって定義されている同じ名前に基づいて、該当するロールの論理名を定義します。
Webベース・アプリケーションの場合、web.xmlファイル内のadfAuthenticationサーブレットに対してセキュリティ制約を構成できます。この制約は、認証されていないセッションによるサーブレットへのアクセスを禁止します。保護された領域へのリンクに制約で定義されたURLパターンが含まれているかぎり、Webコンテナはユーザーが認証されていない場合ログイン・ページを起動します。
|
注意: adfAuthenticationサーブレットはオプションで、動的な認証を可能にします。つまり、まだログインしていないユーザーが認可を必要とするページにアクセスした場合、ユーザーはログインを求められます。このサーブレットは、success_urlというオプションのパラメータをとります。success_urlを指定した場合、ログインに成功すると、ユーザーはリクエストしたページに移動します。success_urlを指定しない場合、ログインに成功すると、ユーザーはログインを開始したページに戻されます。 |
Oracle ADF Security用にweb.xmlを構成する方法:
ナビゲータでJSPプロジェクトを展開し、web.xmlファイルを右クリックして「プロパティ」を選択します。web.xmlファイルは、プロジェクトのWEB-INFフォルダにあります。
通常どおりに、セキュリティ・ロール、ログイン構成およびセキュリティ制約を定義します(前述の手順を参照)。
ADF認証サーブレットの<servlet>要素を作成するには、エディタの左パネルで「Servlet/JSP」を選択して「新規」をクリックします。次のように入力します。
サーブレット名: adfAuthentication
サーブレット・クラス: oracle.adf.share.security.authentication.AuthenticationServlet
認証に成功した場合に表示されるページのURLを含む初期化パラメータを追加するには、「初期化パラメータ」を選択して「追加」をクリックします。URLを入力しない場合、ユーザーは現在のページに戻ります。
サーブレット・マッピングを作成するには、エディタの左パネルで「サーブレット・マッピング」を選択して「追加」をクリックします。次のように入力します。
URLパターン: /adfAuthentication/*
サーブレット名: adfAuthentication
すべての変更を保存し、「Webアプリケーション・デプロイメント・ディスクリプタ」エディタを閉じます。
図30-4に示すweb.xmlエディタには、adfAuthenticationサーブレットのサーブレット・マッピングの定義が表示されています。
例30-2に、web.xmlファイルに含める必要がある定義のサンプルを示します。
例30-2 サンプルweb.xmlファイルで有効に設定されたOracle ADF Security
<servlet>
<servlet-name>adfAuthentication</servlet-name>
<servlet-class>oracle.adf.share.security.authentication.
AuthenticationServlet</servlet-class>
<init-param>
<param-name>sucess_url</param-name>
<param-value>inputForm.jsp</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>adfAuthentication</servlet-name>
<url-pattern>/adfAuthentication/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>adfAuthentication</web-resource-name>
<url-pattern>/adfAuthentication</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>login.jspx</form-login-page>
<form-error-page>login.jspx</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>user</role-name>
</security-role>
ユーザーが保護されたページへのリンクをクリックし、そのユーザーが認証されていない(認証済のユーザー・プリンシパルが現在SecurityContextにない)場合、Oracle ADF Securityのログイン・サーブレットがコールされ、Webコンテナによってログイン・ページが起動されます。
ユーザーがユーザー名とパスワードを送信すると、そのデータはユーザー情報が格納されているリソース・プロバイダのデータと比較され、一致した場合、リクエストの送信者(ユーザー)は認証されます。ユーザー名がSecurityContextに格納されます。ここには、認可権限を判断するために他のセキュリティ関連情報(ユーザーが属するグループなど)を取得するときにアクセスできます。
Oracle ADF SecurityはOracleAS JAASを実装しているため、認証によって、リクエストの送信者を表すJAASサブジェクトも作成されます。
Oracle ADF Business Componentsアプリケーション内でセキュリティを使用する場合は、ADF Business Componentsアプリケーション・モジュールで認証済ユーザーを認識できるようにする必要があります。これにより、アプリケーションで認証済ユーザーの存在に基づいてアプリケーション・モジュールを作成できます。ユーザーがログインを試行して認証されない場合、該当セッション用にアプリケーション・モジュールは作成されません。
Oracle ADF Business Componentsアプリケーション内でセキュリティを有効にするには、アプリケーション・モジュール構成のjbo.security.enforceプロパティ(bc4j.xcfgファイル内)を編集する必要があります。jbo.security.enforceプロパティをMustに設定した場合は、認証済ユーザーがログインしないと、アプリケーション・モジュールが作成されません。コンテナ管理のセキュリティを使用するどのBusiness Componentsアプリケーションでも、これが1つの要件になります。
Oracle ADF Business Componentsのセキュリティを構成する方法:
アプリケーション・ナビゲータで、データ・モデル・プロジェクトを展開し、該当するアプリケーション・モジュール・ノードを探します。
アプリケーション・モジュール・ノードを右クリックし、「構成」を選択します。
Configuration Managerで、アプリケーションの構成を選択し、「編集」をクリックします。
「Oracle Business Componentの構成」ダイアログで、「プロパティ」タブを選択します。
ADF Business Componentsの構成パラメータの完全なリストが、ダイアログに表示されます。セキュリティに関するプロパティは、jbo.securityで始まっています。
jbo.security.enforceプロパティまでスクロールし、Mustという値を入力します。
「OK」をクリックしてダイアログを閉じ、構成の変更を保存します。
図30-5に示すアプリケーション・モジュール構成SRServiceLocalとセキュリティ・プロパティは、ADF Business ComponentsのSRDemoアプリケーションで表示されます。
ADF Business ComponentsアプリケーションでJAZNレルムを使用するには、BC4J Securityライブラリをユーザー・インタフェース・プロジェクトにエクスポートする必要があります。これにより、ユーザー・インタフェース・プロジェクトからjazn.jarを実行時に使用できます。このライブラリが定義されていないと、アプリケーションでログイン・ユーザーの確認を実行しようとする際に、「NullPointerException in JboJAZNUserManager.isUserInRole()」のような例外が返されます。
ADFBC Securityに必要なライブラリをユーザー・インタフェース・プロジェクトに追加する方法:
アプリケーション・ナビゲータで、ユーザー・インタフェース・プロジェクトを右クリックして、「プロジェクト・プロパティ」を選択します。
「プロジェクト・プロパティ」ダイアログで「ライブラリ」を選択し、利用可能なライブラリのリストを表示します。
スクロールして「BC4J Security」を探し、「エクスポート」が有効になっていることを確認します。
「OK」をクリックしてダイアログを閉じ、設定値を保存します。
図30-6に示すBC4J Securityライブラリは、ユーザー・インタフェース・プロジェクトに表示されます。
ADF Business Componentsアプリケーション・モジュールの構成設定でjbo.security.enforceプロパティをMustに設定した場合、アプリケーション・モジュールはSecurityContextから認証済のユーザー・プリンシパルを取得しないと、指定した構成で作成されません。
adfAuthenticationサーブレットに対してセキュリティ制約を構成する場合は、ADF Business Componentsが提供するセキュリティ・メカニズムとADF Securityを組み合せることができます。アプリケーション内のADFバインディング・オブジェクトに認可権限を付与する場合は、ADF Securityを有効にします。ADF Securityによって提供される認可機能の詳細は、30.7項「Oracle ADF Securityを使用した認可の実装」を参照してください。
|
ヒント: JDeveloper 10.1.3.1メンテナンス・リリース以降は、ADF SecurityプロパティauthorizationEnforceをtrueに設定するだけで、ADF Business Componentsアプリケーション内でセキュリティが自動的に有効になります。この場合、jbo.security.enforceプロパティは不要です。 |
ADF Business ComponentsアプリケーションでADF Securityを有効にすると、アプリケーション・モジュールはJAASセキュリティ・コンテキストではなくADFコンテキストのセキュリティ・コンテキストからプリンシパルを取得します。ADFサーブレット認証の有効化の詳細は、30.3.3項「Oracle ADFによる認証を有効にする方法」を参照してください。
Webアプリケーションのログイン・ページでは、フォームのポスト方法として、J2EEセキュリティ・コンテナ・ログイン・メソッドj_security_checkを使用する必要があります。図30-7は、SRDemoアプリケーションのサンプル・ログイン・ページです。
|
注意: ログイン・ページを作成する場合、JSP要素とJSTLタグを使用できます。ページはJSFXドキュメントとしてフォーマットできますが、JSFとコンテナのセキュリティに関する制約により、JSFコンポーネントは使用できません。 |
ログイン・フォームのWebページの作成方法:
ユーザー・インタフェース・プロジェクトを選択し、新規ギャラリを開いて、「Web Tier - JSP」カテゴリから「JSP」を選択します。「Web Tier - JSF」カテゴリを選択して、ログイン・フォームをJSPXドキュメントとして作成しないでください。
JSPの作成ウィザードで、JSPファイル・タイプとしてJSPXドキュメント・タイプを選択します。ウィザードでは、マネージドBeanを使用せずにJSPXドキュメントを作成できます。
ウィザードの「タグ・ライブラリ」ページで「すべてのライブラリ」を選択し、「選択済のライブラリ」リストにJSTLフォーマット1.1とJSTLコア1.1を追加します。
「終了」をクリックしてウィザードを終了し、JSPXファイルをユーザー・インタフェース・プロジェクトに追加します。
コンポーネント・パレットで「JSTL 1.1 FMT」ページを選択し、「SetBundle」をJSPXドキュメントの構造ウィンドウにドラッグし、title要素の上に表示されるようにします。
「SetBundleの挿入」ダイアログで、「basename」をページのリソース・バンドルを含むパッケージに設定します。たとえば、SRDemoアプリケーションでは、oracle.srdemo.view.resources.UIResourcesです。
オプションで、「Message」を構造ウィンドウに表示されているtitle要素の上にドラッグします。Message要素をダブルクリックし、keyプロパティをリソース・バンドルのページ・タイトル・キーに設定します。たとえば、SRDemoアプリケーションでは、キーはsrlogin.pageTitleです。ページ作成から文字列タイトルの残りを削除します。
コンポーネント・パレットから「HTML Forms」ページを選択し、「Form」をページ本体内にドラッグします。「フォームの挿入」ダイアログで、アクションをj_security_checkに、メソッドをpostに設定します。
ユーザー名の「Text Field」をフォームにドラッグし、名前をj_usernameに設定します。
フォームに「Password Field」をドラッグし、j_passwordという名前を付けます。
フォームに「Submit Button」をドラッグし、ラベルをSign Onに設定します。
コンポーネント・パレットでもう一度「JSTL 1.1 FMT」ページを選択し、2つの「Message」タグをフォームにドラッグして、入力フィールドの横に表示されるようにします。キー・プロパティを設定します。たとえば、SRDemoアプリケーションでは、リソース・キーはsrlogin.passwordとsrlogin.usernameです。
例30-3は、SRDemoアプリケーションのログイン・ページのソース・コードです。このJSPXドキュメントでは、JSFコンポーネントの使用時にセキュリティ・コンテナとの競合が発生しないよう、HTML要素とJSTLタグのみを使用しています。セキュリティ・チェック方法は、<form>要素上に表示され、フォームにはユーザー名とパスワードを受け入れる入力フィールドがあります。これらのフィールドは、それぞれの値をコンテナのログインBean属性のj_usernameとj_passwordに割り当てます。
例30-3 SRLogin.jspxからのサンプル・ソース
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=windows-1252"/>
<fmt:setBundle basename="oracle.srdemo.view.resources.UIResources"/>
<title>
<fmt:message key="srdemo.login"/>
</title>
</head>
<body>
... omitting the "number of attempts" checking logic ...
<form action="j_security_check" method="post">
<table cellspacing="3" cellpadding="2" border="0" width="100%">
<tr>
<td colspan="3">
<img height="69" width="340"
src="/SRDemo/faces/images/SRBranding.gif"
alt="SRDemo Logo"/>
<hr/>
</td>
</tr>
<tr>
<td colspan="3">
<h1>
<fmt:message key="srlogin.pageTitle"/>
</h1>
</td>
</tr>
<tr>
<td colspan="3">
<c:if test="${sessionScope.loginAttempts >0}">
<h3><fmt:message key="srdemo.badLogin"/></h3>
</c:if>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td> </td>
<td rowspan="7">
<table border="1" cellpadding="5">
<tr>
<td>
<fmt:message key="srlogin.info"/>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td width="120">
<b><fmt:message key="srlogin.username"/></b>
</td>
<td>
<input type="text" name="j_username"/>
</td>
</tr>
<tr>
<td width="120">
<b><fmt:message key="srlogin.password"/></b>
</td>
<td>
<input type="password" name="j_password"/
</td>
</tr>
<tr>
<td> </td>
<td>
<input type="submit" name="logon" value="Sign On"/>
</td>
</tr>
<tr>
</tr>
<td>&nbsp;</td>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td colspan="3">
<hr/>
</td>
</tr>
</table>
</form>
</c:if>
</body>
</html>
Webコンテナが認証を実行できるように、web.xmlファイルには、ログイン構成情報を含める必要があります。ログイン用に表示するページとユーザーの認証ができなかったためにログインに失敗したときに表示するページを指定します。
ログインの処理方法の構成:
アプリケーション・ナビゲータで、WEB-INFフォルダにあるweb.xmlを探します。
web.xmlを右クリックして「プロパティ」を選択します。
「Webアプリケーション・デプロイメント・ディスクリプタ」ダイアログで、「ログイン構成」を選択します。
「フォームベース認証」を選択し、ログイン・ページとエラー・ページ用のパス名を入力します。ログイン・ページとエラー・ページ用に指定するパスは、ユーザーの認証に使用されるドキュメント・ルートを基準とした相対パスです。たとえば、SRDemoアプリケーションでは、ログインおよびエラー用の両方のページにパスinfrastructure/SRLogin.jspxが使用されています。
図30-8に示すweb.xmlエディタには、ログイン構成の定義が表示されています。
web.xmlのログイン構成情報を定義すると、JDeveloperは次のような定義を作成します。
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>infrastructure/SRLogin.jspx</form-login-page>
<form-error-page>infrastructure/SRLogin.jspx</form-error-page>
</form-login-config>
</login-config>
フォームベース認証を選択し、ユーザーが記述した認証用のHTMLフォームを指定したため、ページ・サーブレットでは、ユーザーを認証するために指定されたJSPページが検索されます。JSPページは、特定のネーミング規則に準拠したフォームが含まれるHTMLページを返す必要があります。同様に、認証に失敗した場合、該当サーブレットは表示するページを探します。SRDemoアプリケーションの場合は、異なるページを定義できますが、いずれの場合も同じページが表示されます。
認証サーブレットの起動をHTMLフォームに許可する規則を、例30-3に示します。具体的には、該当フォームでは次の3つの情報を指定する必要があります。
<form action="j_security_check" method="post">: コンテナのログインBeanのセキュリティ・チェック・メソッドj_security_checkを起動します。
<input type="text" name="j_username"/>: ユーザー名の値をコンテナのログインBeanの属性j_usernameに割り当てます。
<input type="password" name="j_password"/>: パスワードの値をコンテナのログインBeanの属性j_passwordに割り当てます。
HTMLフォームは、ログインBean属性の値を、正確な名前で返す必要があります。JSF JSPページでは、この動作はJSFフォームにより保証されません。そのため、HTMLフォームを使用してログインBean属性名を保持するには、JSPドキュメント・ページを使用してください。
ログアウト・ページは、グローバル・メニュー・ページを含む任意のページに表示されるグローバル・ログアウト・ボタンからコールできます。ログアウト・ページの目的は、ユーザーに終了するかどうかを確認するためのプロンプトを表示することです。ユーザーがログアウトを選択すると、ユーザーのセッションは無効となり、アプリケーションの初期画面に戻ります。アプリケーションを続行するには、もう一度ログインする必要があります。図30-9は、SRDemoアプリケーションのサンプル・ログアウト・ページです。
ログアウト・ページの作成方法:
ユーザー・インタフェース・プロジェクトを選択し、新規ギャラリを開いて、「Web Tier - JSF」カテゴリから「JSF JSP」を選択します。ここでは、JSFコンポーネントを使用できます。
JSF JSPの作成ウィザードで、JSF JSPファイル・タイプとして「JSPドキュメント」タイプを選択します。ここでは、JSFコンポーネントを使用するJSPXドキュメントを作成します。
「コンポーネント・バインディング」ページで、マネージドBeanを作成しないでください。
ウィザードの「タグ・ライブラリ」ページで、「選択済のライブラリ」リストに「ADF Faces Components」と「ADF Faces HTML」を追加します。
「終了」をクリックしてウィザードを終了し、JSPXファイルをユーザー・インタフェース・プロジェクトに追加します。
コンポーネント・パレットで「ADF Faces Core」ページを選択し、コンポーネントDocument、FormおよびPanelPageを、PanelPageがForm内に、FormがDocument内にネスト表示されるようにドラッグします。
次に、コンポーネントPanelBox、PanelHeaderおよびPanelButtonBarを、PanelButtonBarがPanelHeader内に、PanelHeaderがPanelBox内にネスト表示されるようにドラッグして、コマンド・ボタンのPanelPageコンテナを構成します。すべてがPanelPage内でネストされている必要があります。
ユーザーがログアウトするかどうかを選択できるボタンを作成するには、2つのCommandButtonコンポーネントをPanelButtonBar内にドラッグします。
最初のボタンはログアウト機能を提供します。マネージドBeanを作成して個別に関連付けることができます。詳細は、30.6.1項「ログアウト・アクションの関連付け」を参照してください。
2番目のボタンは、アクションGlobalHomeを起動して、ユーザーを希望のページに移動します。このアクションは、ナビゲーション・ルールを使用してfaces-config.xmlファイルで定義します。
例30-4は、SRDemoアプリケーションのログアウト・ページのソース・コードです。このJSPXドキュメントはセキュリティ・コンテナと対話しないため、JSFコンポーネントの使用に関する制約がありません。ログアウト機能を起動するアクションは、ログアウトのラベルを持つ<af:commandButton>に表示されます。
例30-4 SRLogout.jspxからのサンプル・ソース
<af:form>
<af:panelPage title="#{res['srlogout.pageTitle']}">
<!--Page Content Start-->
<af:panelBox>
<af:panelHeader text="#{res['srlogout.subTitle']}"
messageType="warning">
<af:outputText value="#{res['srlogout.text']}"/>
<af:panelButtonBar>
<af:commandButton text="#{res['srlogout.logout.label']}"
action="#{backing_SRLogout.logoutButton_action}"/>
<af:commandButton text="#{res['srlogout.goBack.label']}"
action="GlobalHome"/>
</af:panelButtonBar>
</af:panelHeader>
</af:panelBox>
<!-- Page Content End -->
... omitting facets related to the visual design of the page ...
</af:panelPage>
</af:form>
JSPXドキュメントは、ログアウト・ページのログアウト・コマンド・ボタンに対応するプロパティを持つマネージドBeanを使用して、ログアウト・アクションを処理できます。
ログアウト・アクションの処理方法:
ログアウト・ページを開いて、ログアウト・アクション用に予約したコマンド・ボタンをダブルクリックします。
「アクション」プロパティ・ダイアログで、「メソッド・バインディング」が選択された状態で「新規」をクリックし、マネージドBeanクラスを定義します。
「マネージドBeanの作成」ダイアログで、マネージドBeanの新しいクラス・ファイル名を指定し、faces-config.xmlファイルに登録するマネージドBeanの名前を入力します。
「アクション」プロパティ・ダイアログで「新規」をクリックして、コンポーネントの結果値を設定する文字列を返すためにマネージドBeanクラスに実装するメソッドの名前を指定します。
図30-10に示す「アクション」プロパティ・ダイアログには、backing_SRLogoutというマネージドBeanとlogoutButton_action()というメソッドが入力されています。
生成された.javaファイルで、ユーザーを適切なページに戻すコマンド・ボタンのメソッド・ハンドラを実装します。例30-5のサンプルを参照してください。
|
警告: アプリケーションがHTTPセッションでinvalidate()メソッドをコールして、ログオフ時に現行セッションを終了する場合は、リダイレクトを使用してホームページに戻り、ADF Modelバインディング・コンテナへのアクセスを求める必要があります。データ・バインドされたページにリダイレクトすることで、HTTPセッションの無効化後にADFバインディング・コンテキストが確実に再作成されます。 |
例30-5は、SRDemoアプリケーションのログアウト・ページのマネージドBeanからのメソッド・ハンドラです。logoutButton_action()メソッドによりセッションが無効化され、ホームページにリダイレクトされます。セキュリティ・コンテナからユーザーに自動的に再認証が求められます。
例30-5 SRLogout.javaからのサンプル・ソース
public String logoutButton_action() throws IOException{
ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
HttpServletResponse response = (HttpServletResponse)ectx.getResponse();
HttpSession session = (HttpSession)ectx.getSession(false);
session.invalidate();
response.sendRedirect("SRWelcome.jspx");
return null;
}
コマンド・ボタンのactionプロパティを定義すると、JDeveloperは起動するマネージドBeanおよびBeanメソッドの名前を使用して、Logout.jspxページのソース・コードを更新します。
<af:commandButton text="#{res['srlogout.logout.label']}"
action="#{backing_SRLogout.logoutButton_action}"/>
また、faces-config.xmlファイルが更新されてマネージドBeanが定義されます。
<managed-bean>
<managed-bean-name>backing_SRLogout</managed-bean-name>
<managed-bean-class>oracle.srdemo.view.backing.SRLogout</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
ユーザーがログアウト・ボタンをクリックすると、Faces構成ファイルからJSFコントローラが対応するクラス・ファイルを識別し、アクション・ハンドラ・メソッドの名前をマネージドBeanに渡します。例30-5で示したアクション・ハンドラは、該当するセッションを無効にし、ホームページに戻ります。
認可を使用すると、アクセスを試みるユーザーに基づいて、リソースへのアクセスを制限できます。Oracle ADF Securityは、セキュリティ対応リソースの認可用にOracleAS JAASを実装しています。
Oracle ADF Securityによってセキュリティのレベルを細かく設定し、JAASを使用したJava権限に基づいてオブジェクト・インスタンスへのアクセスを制御できます。具体的には、特定のOracle ADF Modelレイヤー・オブジェクトは「セキュリティ対応」です。つまり、開発者が特定のリソースに対して許可できるコンポーネント固有の権限が事前に定義されています。
|
注意: SRDemoアプリケーションでは、現在ADF ModelレイヤーでのOracle ADF Securityのデモを行えません。SRDemoアプリケーションでの認可の処理方法の詳細は、30.8項「プログラムによる認可の実装」を参照してください。 |
次のOracle ADFオブジェクトはセキュリティ対応オブジェクトで、各データ・バインドWebページに関連付けられたページ定義ファイルによって定義されます。
バインディング・コンテナ
イテレータ・バインディング
属性バインディング
MethodActionバインディング
これらのオブジェクトへの権限を設定するには、そのオブジェクト(リソース)で特定のアクションを実行する権限を持つ認証済ユーザーまたはロールを定義します。権限受領者はプリンシパルとして定義されたロール、ユーザーまたはグループで、権限にマップされます。権限とは、Oracle ADF Securityクラスによって定義される、リソースに対して特定のアクションを実行できる権限です(詳細はOracle ADFのJavadocを参照)。権限は集約されます。つまり、グループのロールに権限が付与されて、ユーザーがそのグループに属している場合、ユーザーにもこれらの権限が与えられます。付与が実行されないと、ロール、ユーザーまたはグループによるアクセスが拒否されます。
表30-1に、バインディング・コンテナ、イテレータ・バインディング、属性レベル・バインディング(表、リスト、ブール、属性値バインディング)、メソッド・バインディングに付与できる権限を示します。実行時にページ定義ファイルから作成されるOracle ADFオブジェクトでユーザーに権限を付与するには、認可エディタを使用します。
表30-1 Oracle ADF Securityの認可権限
| ADF Modelオブジェクト | 定義済のアクション | ユーザー・インタフェースのコンポーネントへの影響 |
|---|---|---|
|
Webページのバインディング・コンテナ |
grant: ページでの権限を管理できる。 |
実行時のカスタマイズが可能なページで、アクセス制御を設定するように構成されたリンクまたはボタンは、この権限を付与されていないユーザーに対して無効になります。 |
|
edit: ページのコンテンツを編集できる。 |
ユーザーに表示アクション権限が付与され、編集アクション権限は付与されていない場合、入力テキスト・ボックスのデータは読取リ専用として表示されます。 |
|
|
personalize: ページのユーザー・カスタマイズが可能。 |
実行時のカスタマイズが可能なページで、ページをパーソナライズ・モードにするように構成されたリンクまたはボタンは、この権限を付与されていないユーザーに対して無効になります。 |
|
|
view: ページを表示できる。 |
この権限を付与されていないユーザーには認可エラーが表示されます。 |
|
|
イテレータ・バインディング |
read: 返された行を読み取れる。 |
すべてのデータ行が返されます。ただし、個々の属性バインディングに権限を付与することで、表示または更新可能な行を制限できます。 |
|
update: 行のデータを更新できる。 |
コミット操作がデータ・コントロール・パレットからコマンド・ボタンとしてドロップされている場合、この権限を付与されていないユーザーに対してボタンは無効になります。行全体の更新を制限するかわりに、個々の属性の更新を制限できます。 |
|
|
create: 新しい行を作成できる。 |
作成操作がデータ・コントロール・パレットからコマンド・ボタンとしてドロップされている場合、この権限を付与されていないユーザーに対してボタンは無効になります。 |
|
|
delete: 行を削除できる。 |
削除操作がデータ・コントロール・パレットからコマンド・ボタンとしてドロップされている場合、この権限を付与されていないユーザーに対してボタンは無効になります。 |
|
|
メソッド・アクション・バインディング |
invoke: メソッドを実行できる。 |
メソッドがコマンド・ボタンにバインドされている場合、この権限を付与されていないユーザーに対してボタンは無効になります。メソッドが暗黙的に起動される場合、メソッドはこの権限を付与されたユーザーの場合のみ実行されます。 |
|
属性レベル・バインディング |
read: 属性の値を読み取れる。 |
属性の値が表示されます。 |
|
update: 属性の値を更新できる。 |
この権限を付与されていないユーザーには、入力テキスト・ボックスのデータは読取り専用として表示されます。 |
Oracle ADFによる認可を実装する前に、次のことを行う必要があります。
ADF Authenticationサーブレットの認証を構成します。詳細は、30.3.3項「Oracle ADFによる認証を有効にする方法」を参照してください。
Oracle ADF Securityによる認可を使用するようにアプリケーションを構成します。詳細は、30.7.1項「Oracle ADF Securityによる認可を使用するようにアプリケーションを構成」を参照してください。
アプリケーションでADFによる認可を使用する前に、Oracle ADF Securityを使用するようにアプリケーションを構成する必要があります。
Oracle ADF Securityによる認可を有効にするには、Oracle ADF Securityを使用するようにアプリケーションのコンテナを設定する、adf-config.xmlという名前の構成ファイルを作成する必要があります。このファイルによって、ADFContextとSecurityContextが初期化されます。
Oracle ADF Securityを使用するようにアプリケーションを構成する方法:
セキュリティを必要とするプロジェクトを右クリックし、「新規」を選択します。
新規ギャラリで「XML」カテゴリを選択します。
XMLが表示されない場合は、上部の「フィルタ方法」リストを使用して「すべてのテクノロジ」を選択します。
「項目」リストで「XML文書」を選択し、「OK」をクリックします。
ファイルにadf-config.xmlという名前を付け、<application_name>/.adf/META-INFディレクトリに保存して、「OK」をクリックします。
ソース・エディタにファイルが開きます。
生成されたコードを次のように置き換えます。
<?xml version="1.0" encoding="windows-1252" ?>
<adf-config xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance "
xsi:schemaLocation=" http://xmlns.oracle.com/adf/config
../../../../../bc4jrt/src/oracle/adf/share/config/schema/config.xsd"
xmlns=" http://xmlns.oracle.com/adf/config "
xmlns:sec=" http://xmlns.oracle.com/adf/security/config ">
<sec:adf-config-child xmlns=" http://xmlns.oracle.com/adf/security/config ">
<JaasSecurityContext
initialContextFactoryClass="oracle.adf.share.security.
JAASInitialContextFactory"
authorizationEnforce="true"
jaasProviderClass="oracle.adf.share.security.providers.jazn.
JAZNSecurity Context" >
</JaasSecurityContext>
</sec:adf-config-child>
</adf-config>
ファイルを保存して閉じます。
<JaasSecurityContext>要素のauthorizationEnforceパラメータがTrueに設定されている場合、認証されたユーザー・プリンシパルを、認証後ADF SecurityContextに入れることができます。
|
ヒント: Oracle ADF Securityを使用せずにアプリケーションを実行する場合は、authorizationEnforceパラメータをFalseに設定します。 |
セキュリティのオンとオフは切り替えられるので、認可チェックを起動する前にアプリケーションでこのプロパティの設定を決定することをお薦めします。アプリケーションは、認可プロパティの設定をチェックして、Oracle ADF Securityが有効かどうかを判断できます。これは、ADFContextの下にあるSecurityContextのisAuthorizationEnabled()メソッドから公開されます。たとえば、次のように入力します。
if (ADFContext.getCurrent().getSecurityContext().isAuthorizationEnabled())
{
Permission p = new RegionPermission("view.pageDefs.page1PageDef", "Edit");
AccessController.checkPermission(p);
// do the protected action
} catch (AccessControlException ace) {
// do whatever's appropriate on an access denied
}
|
注意: JDeveloper 10.1.3.1メンテナンス・リリース以降は、ADF SecurityプロパティauthorizationEnforceをtrueに設定するだけで、ADF Business Componentsアプリケーションのセキュリティが自動的に有効になります。この場合、jbo.security.enforceプロパティは不要です。ADF Business Componentsによるセキュリティの実行については、30.4項「コンテナ管理のセキュリティを使用するためのADF Business Componentsアプリケーションの構成」を参照してください。 |
認可エディタを使用して、ページ定義全体で定義されているとおりに、バインディング・コンテナに対するユーザーの権限を付与します。Oracle ADFの権限の詳細は、表30-1を参照してください。
認可エディタを使用したバインディング・コンテナでの権限の付与方法:
Webページを作成します。ビジュアル・エディタからページを右クリックし、「ページ定義に移動」を選択します。
構造ウィンドウでルート・ノードのPageDefを右クリックし、「認可の編集」を選択します。
認可エディタには、リソース・プロバイダで定義されたプリンシパル(ロールおよびユーザー)とともに、バインディング・コンテナの事前定義済の権限が表示されます。
このダイアログの使用方法の詳細は、「ヘルプ」をクリックするか[F1]を押してください。
認可エディタを使用して、ユーザーにイテレータ・バインディングでの権限を付与します。Oracle ADFの権限の詳細は、表30-1を参照してください。
認可エディタを使用したイテレータでの権限の付与方法:
Webページを作成します。ビジュアル・エディタからページを右クリックし、「ページ定義に移動」を選択します。
構造ウィンドウで、executablesノードを展開します。
権限を付与するイテレータを右クリックし、「認可の編集」を選択します。
認可エディタには、リソース・プロバイダで定義されたプリンシパル(ロールおよびユーザー)とともに、イテレータの事前定義済の権限が表示されます。
このダイアログの使用方法の詳細は、「ヘルプ」をクリックするか[F1]を押してください。
認可エディタを使用して、ユーザーに属性およびメソッド・アクション・バインディングでの権限を付与します。
属性について付与された権限は、作成、削除、コミットなどの操作を実行する権限を表します。したがって、操作に対してではなく、属性またはイテレータに対して認可を設定してください。Oracle ADFの権限の詳細は、表30-1を参照してください。
認可エディタを使用した属性およびメソッド・バインディングでの権限の付与方法:
Webページを作成します。ビジュアル・エディタからページを右クリックし、「ページ定義に移動」を選択します。
構造ウィンドウで、bindingsノードを展開します。
権限を付与する属性またはメソッド・アクション・バインディングを右クリックし、「認可の編集」を選択します。
認可エディタには、リソース・プロバイダで定義されたプリンシパル(ロールおよびユーザー)とともに、属性またはメソッド・アクション・バインディングの事前定義済の権限が表示されます。
このダイアログの使用方法の詳細は、「ヘルプ」をクリックするか[F1]を押してください。
ユーザーが定義済の権限を持つリソースに対してアクションを実行しようとすると、Oracle ADF Securityは、ユーザーが権限で定義されたプリンシパルかどうかを確認します。ユーザーがまだ認証されていない場合、ログイン・ページまたはフォームが表示されます。認証されたユーザーでも権限がない場合は、セキュリティ・エラーが表示されます。
例30-6に、Oracle JAZN軽量XMLプロバイダを使用する場合の属性バインディングおよびメソッド・バインディングに対する権限を示します。これらの権限は、system-jazn-data.xmlファイルに書き込まれます。これらの権限では、usersというロールにはバインドされたコレクションEmployeesView1の属性の作成、読取りおよび更新を実行するためのRowSetPermissionと、DepartmentIDの属性値を読み取るためのAttributePermissionが付与されています。
例30-6 サンプルsystem-jazn-data.xmlファイルのOracle ADFの権限
<grant>
<grantee>
<principals>
<principal>
<realm-name>jazn.com</realm-name>
<type>role</type>
<class>oracle.security.jazn.spi.xml.XMLRealmRole</class>
<name>jazn.com/users</name>
</principal>
</principals>
</grantee>
<permissions>
<permission>
<class>oracle.adf.share.security.authorization.RowSetPermission</class>
<name>EmployeesView1</name>
<actions>create,read,update</actions>
</permission>
<permission>
<class>oracle.adf.share.security.authorization.AttributePermission</class>
<name>EmployeesView1.DepartmentId</name>
<actions>read</actions>
</permission>
</permissions>
</grant>
ユーザーまたはロールは、リソース・プロバイダで定義されています。
リソースとユーザーに対して認可ポリシーを設定できます。たとえば、特定のユーザー・グループのみに、特定データの表示、作成、変更や特定メソッドの起動を許可できます。ユーザーが属するグループに基づいて、コンポーネントのレンダリングを禁止することもできます。ユーザーは認証されているため、アプリケーションはそのユーザーに認可制約のあるオブジェクトへのアクセスを許可するかどうかを決定できます。
アプリケーションはプログラムでロールを参照し、特定のユーザーがそのロールに属しているかどうかを確認できます。SRDemoアプリケーションでは、この操作にFacesContextインタフェースで定義された(HttpServletRequestインタフェースからも使用できる)メソッドisUserInRole()を使用しています。
SRDemoアプリケーションは、3つのコア・ロールを使用して、特定機能を実行できるユーザーを決定します。各ユーザーは、user、technicianまたはmanagerのロールに分類されます。remoteUser値(FacesContextから取得)は、SRDemoアプリケーションのUSERS表の電子メール・アドレスと一致します。これらの基準は、30.3.1項「J2EEコンテナ管理の認証を有効にする方法」で説明したように、Oracle Application Serverが提供するコンテナ管理のフォームベース認証を使用して実装されています。
セキュリティ・コンテナの設定後、認証によって次のことが行われます。
アプリケーションが初めて参照したときに、コンテナのセキュリティ属性を読み取ります。
式言語を通してアクセス可能なフォームで主要なセキュリティ情報を使用できるようにします。
これを実現するために、JSF Webアプリケーションでは、セッション・スコープに登録されたマネージドBeanを利用できます。マネージドBeanは、faces-config.xmlファイルを使用してアプリケーションに登録するJavaクラスです。アプリケーションを起動すると、アプリケーションはこの構成ファイルを解析し、Beanを利用可能にして、EL式で参照できるようにします。その結果、WebページからBeanのコンテンツへのアクセスが可能となります。
マネージドBeanの使用の詳細は、17.2項「マネージドBeanを使用した情報の格納」を参照してください。
次のSRList.jspxからのサンプルは、managerが編集ページの表示に使用するボタンをWebページに表示するかどうかを制御します。
<af:commandButton text="#{res['srlist.buttonbar.edit']}"
actionListener="#{bindings.setCurrentRowWithKey.execute}"
action="Edit"
rendered="#{userInfo.manager}">
<af:setActionListener from="#{row.rowKeyStr}"
to="#{processScope.rowKeyStr}"/>
<af:setActionListener from="#{'GlobalHome'}"
to="#{userState.returnNavigationRule}"/>
</af:commandButton>
次のSRCreateConfirm.jspxからのサンプルは、ユーザーの認証ステータスに基づいて、ユーザー名をWebページに表示するかどうかを制御します。
<f:facet name="infoUser">
<!-- Show the Logged in user -->
<h:outputFormat value="#{res['srdemo.connectedUser']}"
rendered="#{userInfo.authenticated}" escape="false">
<f:param value="#{userInfo.userName}"/>
</h:outputFormat>
</f:facet>
マネージドBeanのプロパティを使用して、ユーザーを検証し、使用可能なロールを判断するために必要なコードを含むクラスのメソッドを起動できます。このクラスは、マネージドBeanを作成する前に作成して、マネージドBeanを定義するときに使用するプロパティ名がわかっているようにする必要があります。
Javaクラスの作成方法:
新規ギャラリで、「General」カテゴリと「Javaクラス」項目を選択します。
「Javaクラスの作成」ダイアログで、クラス名を入力し、デフォルト値を受け入れて、デフォルト・コンストラクタとともにpublicクラスを作成します。
例30-7に、SRDemoアプリケーションが実装している主要メソッドを示します。
例30-7 SRDemoアプリケーションのUserInfo.javaサンプル
/**
* Constructor
*/
public UserInfo() {
FacesContext ctx = FacesContext.getCurrentInstance();
ExternalContext ectx = ctx.getExternalContext();
//Ask the container who the user logged in as
_userName = ectx.getRemoteUser();
//Default the value if not authenticated
if (_userName == null || _userName.length()==0) {
_userName = "Not Authenticated";
} //Set the user role flag...
//Watch out for a tricky bug here:
//We have to evaluate the roles Most > Least restrictive
//because the manager role is assigned to the technician and user roles
//thus checking if a manager is in "user" will succeed and we'll stop
//there at the lower level of priviledge
for (int i=(ROLE_NAMES.length-1);i>0;i--) {
if (ectx.isUserInRole(ROLE_NAMES[i])){
_userRole = i;
break;
}
}
} /**
* @return the String role name
*/
public String getUserRole() {
return ROLE_NAMES[_userRole];
} /**
* Get the security container user name of the current user.
* As an additional precaution make it clear when we are running in
* Dev mode.
* @return users login name which in this case is also their email id. */
public String getUserName() {
StringBuffer name = new StringBuffer(_userName);
if (_devMode) {
name.append(" (Development Mode)");
}
return name.toString();
} /**
* Function designed to be used from Expression Language
* for swiching UI Features based on role.
* @return boolean
*/
public boolean isCustomer() {
return (_userRole==USER_ROLE);
} /**
* Function designed to be used from Expression Language
* for switching UI Features based on role.
* @return boolean
*/
public boolean isTechnician() {
return (_userRole==TECHNICIAN_ROLE);
} /**
* Function designed to be used from Expression Language
* for switching UI Features based on role.
* @return boolean
*/
public boolean isManager() {
return (_userRole==MANAGER_ROLE);
} /**
* Function designed to be used from Expression Language
* for switching UI Features based on role.
* This particular function indicates if the user is either
* a technician or manager
* @return boolean
*/
public boolean isStaff() {
return (_userRole>USER_ROLE);
} /**
* Function designed to be used from Expression Language
* for switching UI Features based on role.
* This particular function indicates if the session is actually authenticated
* @return boolean
*/
public boolean isAuthenticated() {
return (_userRole>NOT_AUTHENTICATED);
}
}
UserInfo Beanは、JSF faces-config.xml ファイルでuserInfoという名前のマネージドBeanとして登録されます。マネージドBeanでは、UserInfo.javaクラスが実装する管理プロパティの式を使用します。
たとえば、SRDemoアプリケーションのUserInfoマネージドBeanには次の式があります。
#{userInfo.userName}は、ログインIDまたは文字列「Not Authenticated」を返します。
#{userInfo.userRole}は、managerなどの文字列値で、現行ユーザーのロールを返します。
#{userInfo.staff}は、ユーザーがtechnicianまたはmanagerの場合にTrueを返します。
#{userInfo.customer}は、ユーザーがuserというロールに属しているときにTrueを返します。
#{userInfo.manager}は、ユーザーがmanagerの場合にTrueを返します。
マネージドBeanのプロパティと式の定義方法:
アプリケーション・ナビゲータで、ユーザー・インタフェースのWEB-INFフォルダのfaces-config.xmlファイルを開きます。
ウィンドウで「概要」タブを選択します。
左側の要素リストで「Managed Bean」を選択し、「新規」をクリックします。
「マネージドBeanの作成」ダイアログで、マネージドBeanのクラス情報を指定します。クラスを作成していない場合は、30.8.1.1項「ロールを管理するクラスの作成」を参照してください。
マネージドBeanで定義されたセキュリティ情報に複数のWebページがアクセスできるようにするには、「有効範囲」を「セッション」に設定します。たとえば、SRDemoアプリケーションでは、UserInfo.javaクラスに対応するマネージドBean名userInfoを定義します。
例30-8は、SRDemoアプリケーションのセキュリティ情報を保持するマネージドBean userInfoを定義する、faces-config.xmlファイルの一部です。
例30-8 SRDemoのfaces-config.xmlファイルのマネージドBean
<!-- The managed bean used to hold security information -->
<managed-bean>
<managed-bean-name>userInfo</managed-bean-name>
<managed-bean-class>oracle.srdemo.view.UserInfo</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>