AEMで管理セッションまたはリソースリゾルバーを取得する主な方法は、Slingが提供するSlingRepository.loginAdministrative()
メソッドとResourceResolverFactory.getAdministrativeResourceResolver()
メソッドを使用することです。
ただし、これらのメソッドはいずれも最小権限の原則に基づいて設計されておらず、開発者がコンテンツの構造や対応するアクセス制御レベル(ACL)を早期に適切に計画しないことがよくあります。そのため、このようなサービスに脆弱性があると、コード自体を動作させるのに管理者権限が不要であっても、admin
ユーザーへの権限のエスカレーションが発生することがよくあります。
管理セッションが使用されていなかったり、機能が完全に無効化されている場合があります。現在の実装環境がこれに当てはまる場合は、機能を削除するか、NOP コードを埋め込んでください。
可能な限り、機能のリファクタリングをおこなって、コンテンツの読み取りや書き込みに特定の認証済み要求セッションを使用できるようにしてください。それが可能でなくても、ほとんどの場合は、以降で説明する方法に従って優先度を適用することによって対応できます。
問題の多くは、コンテンツを再構築することによって解決できます。再構築する際には、次の単純なルールに留意してください。
アクセス制御を変更する
コンテンツ構造を調整する
コードのリファクタリングをおこなって適切なサービスになるようにする
また、新機能を開発する場合は、次の原則に従ってください。
セキュリティ要件に従ってコンテンツ構造を決定する
ノードタイプを使用する
プライバシー設定に配慮する
/profile
ノード上のプロファイルの画像、電子メール、またはフルネームを公開しないことが考えられます。コンテンツの再構築時にアクセス制御を適用する場合でも、新しいサービスユーザーに対して適用する場合でも、可能な限り厳密なACLを適用する必要があります。 考えられるすべてのアクセス制御機能を使用してください。
例えば、/apps
にjcr:read
を適用する代わりに、/apps/*/components/*/analytics
にのみ適用します
制限を使用します。
ノードタイプに ACL を適用します。
権限を制限します。
jcr:write
権限を与えないでください。代わりにjcr:modifyProperties
を使用上記の処理が失敗した場合、Sling 7ではService User Mappingサービスがオファーされます。これにより、バンドルとユーザーのマッピングと、対応する2つのAPIメソッドを設定できます。 [SlingRepository.loginService()](https://sling.apache.org/apidocs/sling7/org/apache/sling/jcr/api/SlingRepository.html#loginService-java.lang.String-java.lang.String-)
と [ResourceResolverFactory.getServiceResourceResolver()](https://sling.apache.org/apidocs/sling7/org/apache/sling/api/resource/ResourceResolverFactory.html#getServiceResourceResolver-java.util.Map-)
は、設定されたユーザーのみの権限を持つセッション/リソースリゾルバを返します。 これらのメソッドの特徴は次のとおりです。
サービスをユーザーにマッピングできます。
サブサービスユーザーを定義できます。
中央設定ポイントは org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl
です。
service-id
= service-name
[ ":" subservice-name ]
service-id
は、認証用にリソースリゾルバーまたは JCR リポジトリユーザー ID(あるいはその両方)にマッピングされます。
service-name
は、サービスを提供するバンドルの記号名です。
サービスユーザーとは、パスワードを設定しておらず、特定のタスクを実行するために必要な最小限の権限を持つ JCR ユーザーのことです。パスワードを設定していないということは、サービスユーザーとしてはログインできないことを意味します。
管理セッションを廃止するには、管理セッションをサービスユーザーセッションに置き換えます。必要に応じて、複数のサブサービスユーザーに置き換えることもできます。
管理セッションをサービスユーザーに置き換えるには、次の手順を実行します。
最小権限の原則を念頭に置いて、サービスに必要な権限を特定します。
必要な権限が正確に設定されたユーザーが既に存在するかどうかをチェックします。既存のユーザーがニーズを満たさない場合は、新しいシステムサービスユーザーを作成します。新しいサービスユーザーを作成するには、RTC が必要です。場合によっては、複数のサブサービスユーザー(例えば、書き込み用と読み取り用にそれぞれ 1 つ)を作成して、アクセスをさらに区分化します。
ユーザーに対する ACE を設定してテストします。
ご追加使用のサービスとuser/sub-users
のservice-user
マッピング
サービスユーザーの sling 機能をバンドルから使用できるようにします。つまり、org.apache.sling.api
を最新バージョンに更新します。
コード内のadmin-session
をloginService
またはgetServiceResourceResolver
APIに置き換えます。
ユースケースに適したユーザーが AEM サービスユーザーのリストに存在せず、対応する RTC の発行が承認されていることを確認したら、デフォルトコンテンツに新しいユーザーを追加できます。
推奨されるアプローチは、https://<server>:<port>/crx/explorer/index.jspにあるリポジトリエクスプローラーを使用するサービスユーザーを作成することです。
目的は、有効な jcr:uuid
プロパティを取得することです。このプロパティは、コンテンツパッケージのインストール環境を使用してユーザーを作成する場合に必須です。
サービスユーザーは次の方法で作成できます。
https://<server>:<port>/crx/explorer/index.jspにあるリポジトリエクスプローラーに移動します。
画面の左上隅にある「ログイン」リンクをクリックして、admin としてログインします。
次に、システムユーザーを作成して名前を付けます。ユーザーをシステムユーザーとして作成するには、中間パスとして system
を設定し、ニーズに合わせてオプションのサブフォルダーを追加します。
システムユーザーノードが次のようになっていることを確認します。
サービスユーザーに mixin タイプが関連付けられていないことに注意してください。これは、システムユーザーに対するアクセス制御ポリシーが存在しないことを意味します。
対応する .content.xml をバンドルのコンテンツに追加する際には、rep:authorizableId
を設定し、プライマリタイプを rep:SystemUser
にしてください。次のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:rep="internal"
jcr:primaryType="rep:SystemUser"
jcr:uuid="4917dd68-a0c1-3021-b5b7-435d0044b0dd"
rep:principalName="authentication-service"
rep:authorizableId="authentication-service"/>
サービスから対応するシステムユーザーへのマッピングを追加するには、 [ServiceUserMapper](https://sling.apache.org/apidocs/sling7/org/apache/sling/serviceusermapping/ServiceUserMapper.html)
サービスのファクトリ設定を作成する必要があります。この操作をモジュール化するには、Sling 修正メカニズムを使用してこのような設定をおこなうことができます。このような設定をバンドルと共にインストールする場合は、Sling の初期コンテンツ読み込み機能を使用することをお勧めします。
バンドルのsrc/main/resourcesフォルダーの下にサブフォルダーSLING-INF/contentを作成します
このフォルダーに、org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-<some unique name for your factory configuration>.xmlという名前のファイルを作成し、ファクトリ設定の内容(すべてのサブサービスユーザーマッピングを含む)を入力します。 例:
バンドルのsrc/main/resources
フォルダーの下にSLING-INF/content
フォルダーを作成します。
このフォルダーに、すべてのサブサービスユーザーマッピングを含む、ファクトリ構成の内容を含むファイルnamed org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-<a unique name for your factory configuration>.xml
を作成します。
例示のために、org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended-com.adobe.granite.auth.saml.xml
というファイルを取り上げています。
<?xml version="1.0" encoding="UTF-8"?>
<node>
<primaryNodeType>sling:OsgiConfig</primaryNodeType>
<property>
<name>user.default</name>
<value></value>
</property>
<property>
<name>user.mapping</name>
<values>
<value>com.adobe.granite.auth.saml=authentication-service</value>
</values>
</property>
</node>
バンドルのpom.xml
内のmaven-bundle-plugin
の設定でSlingの初期コンテンツを参照します。 例:
<Sling-Initial-Content>
SLING-INF/content;path:=/libs/system/config;overwrite:=true;
</Sling-Initial-Content>
バンドルをインストールし、ファクトリ設定がインストールされていることを確認します。手順は次のとおりです。
loginAdministrative()
への呼び出しは、多くの場合、共有セッションと共に表示されます。 これらのセッションはサービスのアクティベート時に取得され、サービスが停止された場合にのみログアウトされます。これは一般的な方法ですが、次の2つの問題が生じます。
セキュリティ上のリスクの最も明白な解決策は、loginAdministrative()
呼び出しをloginService()
呼び出しに置き換えるだけで、制限付きの権限を持つユーザに対して行うことです。 ただし、この方法は潜在的なパフォーマンスの低下には効果がありません。代わりに、セッションに関連しないオブジェクトに要求されたすべての情報をラップすることによって、パフォーマンスの低下を軽減できる可能性があります。その後、要求に応じてセッションを作成(または破棄)します。
推奨されるアプローチは、サービスの API のリファクタリングをおこなって、呼び出し元がセッションの作成と破棄を制御できるようにすることです。
関連するサービスがないため、JSPはloginService()
を使用できません。 ただし、JSPの管理セッションは、通常、MVCパラダイムの違反の兆候です。
これは次の 2 つの方法で解決できます。
推奨される方法は前者です。
イベントやジョブ、場合によってはワークフローを処理する際には、そのイベントのトリガーとなった該当セッションは通常失われます。その結果、イベントハンドラーやジョブプロセッサーでは、多くの場合、管理セッションを使用して処理がおこなわれます。様々なアプローチによってこの問題を解決できますが、それぞれ利点と欠点があります。
user-id
をイベントペイロードに渡し、代理実行を使用します。
利点: 使いやすさ。
デメリット: まだ使用 loginAdministrative()
中です。認証済みの要求が再認証されます。
データへのアクセス権限を持つサービスユーザーを作成または再利用します。
利点:現在の設計と一貫している。変更が最小限で済みます。
デメリット:非常に強力なサービスユーザーが柔軟に対応できる 必要があり、その結果、特権エスカレーションが容易になります。セキュリティモデルに抜け道ができます。
Subject
のシリアル化をイベントペイロードに渡し、そのサブジェクトに基づいて ResourceResolver
を作成します。例えば、doAsPrivileged
で JAAS ResourceResolverFactory
を使用します。
利点:セキュリティの観点からクリーンな実装。再認証は回避し、元の権限で動作します。セキュリティ関連のコードはイベントの消費者に対して透過的です。
デメリット:リファクタリング が必要です。セキュリティ関連のコードがイベントの消費者に対して透過的であることから、問題に発展する可能性があります。
3 番目のアプローチが現在推奨されている処理手法です。
ワークフロープロセス実装では、ワークフローのトリガーとなった該当ユーザーセッションは通常失われます。その結果、ワークフロープロセスでは、多くの場合、管理セッションを使用して処理がおこなわれます。
このような問題を修正するには、イベント、レプリケーション、プリプロセッサーおよびジョブの処理で説明したものと同じアプローチを使用することをお勧めします。
Sling POST プロセッサーの実装では、いくつかの管理セッションが使用されます。通常、管理セッションは、処理中の POST 内で削除待ちになっているノードにアクセスするために使用されます。そのため、要求セッションからは使用できません。削除待ちのノードにアクセスすると、本来アクセスできないメタデータを取得できます。