私は 2 セットの URL を持っています。1 セットは REST API で、2 セット目はごく普通の Web サイトです。REST API にさまざまなセキュリティ ルールを適用して、REST API をときどき呼び出すユーザー/スクリプトが 401 コード (基本認証で問題ありません) または 403 だけで応答されるようにしたいと考えています。
だから私はREST APIへのアクセスを許可したい:
- ログインしているユーザー (REST API を呼び出すサイト ページの JavaScript の場合、同じセッションを共有します)。
- WWW-Authenticate ヘッダーの基本的な認証資格情報を使用して REST API を呼び出すスクリプト。
現時点では、どの構成がSpringに私が望むものを「理解」させるかを理解しようとしています。次の構成を思いつきました。
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/" security="none" />
<http pattern="/static/**" security="none" />
<!-- REST API -->
<http pattern="/rest/*" use-expressions="true">
<http-basic />
<intercept-url pattern="/*" access="isAuthenticated()" />
</http>
<!-- Site -->
<http access-denied-page="/WEB-INF/views/errors/403.jsp" use-expressions="true">
<intercept-url pattern="/index.html" access="hasRole('ROLE_USER') or hasRole('ROLE_ANONYMOUS')" />
<intercept-url pattern="/login.html" access="hasRole('ROLE_USER') or hasRole('ROLE_ANONYMOUS')" />
<intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login.html"
default-target-url="/index.html"
authentication-failure-url="/login.html?error=1" />
<logout logout-url="/logout.do" logout-success-url="/index.html" />
<anonymous username="guest" granted-authority="ROLE_ANONYMOUS" />
<remember-me />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="admin" password="2" authorities="ROLE_ADMIN,ROLE_USER" />
<user name="alex" password="1" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
残念ながら、この構成では基本認証が機能しないだけでなく、匿名ユーザーによる要求に対する 403 応答がありません - アプリケーションはリダイレクト 302 Found で応答しますが、これは REST API URL に対して許可しないようにしたいと考えています。
REST API のカスタム エントリ ポイントを追加しようとしました。
<beans:bean id="ep403" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<!-- REST API -->
<http pattern="/rest/*" entry-point-ref="ep403" use-expressions="true">
<intercept-url pattern="/*" access="hasRole('ROLE_USER')" />
<http-basic />
</http>
しかし、これも機能しません。
私が取得したいものを要約するには:
- 許可されたユーザーが REST API にアクセスできるようにします (許可機能は、Cookie のユーザー セッションを考慮に入れる必要があります)。
- スクリプトが正しい認証トークンを指定し、Cookie でセッションを指定していない場合、REST API へのアクセスをスクリプトに許可します。
アップデート
Spring Security の内部を掘り下げた後、特定のリクエストを拒否するかどうかを決定するコードを見つけました。これはいわゆる「アクセス決定投票者」であり、基本的にすべてが特定のリクエストに適用され、チェーン内の 1 つのアクセス決定投票者が特定のリソースへのアクセスを拒否するために投票した場合、リクエストは最終的に拒否されます。
したがって、元の問題は、次のように動作する特別なアクセス決定ボーターを導入することで解決される可能性があります。セッションから関連するロールを抽出しようとし (リクエストに存在する場合)、このロールで承認ステップに進みます。セッションが存在しない場合は、WWW-Authenticate ヘッダーの資格情報に対してユーザーを認証しようとし、指定されたユーザーに関連付けられたロールを使用して承認手順に進みます。