5

私は 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 ヘッダーの資格情報に対してユーザーを認証しようとし、指定されたユーザーに関連付けられたロールを使用して承認手順に進みます。

4

3 に答える 3

2

インターセプターを使用して、/rest/パターンを持つ URL をチェックできます。

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/rest/**"/>
            <bean class="com.your.class.name.Interceptor></bean>
        </mvc:interceptor>
</mvc:interceptors>

このために、XML のヘッダー部分に以下の行を追加します。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"

Interceptorクラスで必要なものを確認すると、このクラスは Spring を実装する必要がありますHandlerInterceptor

public class Interceptor implements HandlerInterceptor{

    @Override  
    public boolean preHandle(HttpServletRequest request,  
                             HttpServletResponse response,  
                             Object handler) throws Exception {
       //do what you need to check when the request arrives
       //do authentications here
       //return true if success
       //else false
    }

    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, 
                           Object handler,
                           ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, 
                                Object handler, 
                                Exception ex) throws Exception {    
    }

}

メソッドの詳細については、こちらをお読みください。これも見れる

于 2013-03-21T06:28:38.280 に答える
0

REST API のとに変更pattern="/rest/*"してみてください。pattern="/rest/**"pattern="/*"pattern="/**"

<http pattern="/rest/**" use-expressions="true">
    <intercept-url pattern="/**" access="isAuthenticated()" />
    <http-basic />
</http>
于 2013-03-20T15:41:56.420 に答える