1

Spring Security 3.0.7 を使用しており、アプリケーションは JBOSS にデプロイされています。

アプリケーションにorg.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptorを設定して、サービス層で特定のメソッドの呼び出しに制限を追加しています。しかし、何らかの理由でインターセプターが呼び出されず、ロールROLE_USERを持つユーザーからすべてのメソッドを呼び出すことができます。私の security.xml は次のようになります。

<security:http auto-config='true' authentication-manager-ref="authenticationManager" use-expressions="true" request-matcher="ant" create-session="always"
    entry-point-ref="authenticationEntryPoint" >

    <security:intercept-url pattern="/login.jsp" access="permitAll" />
    <security:intercept-url pattern="/configure/" access="hasRole('ROLE_ADMIN')"  />
    <security:intercept-url pattern="/**" access="isAuthenticated()" />

    <security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=Authentication Failed!" default-target-url="/landing.do" 
    always-use-default-target="true"  />

    <security:logout invalidate-session="true" delete-cookies="true" />


    <security:session-management>
        <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/login.jsp"/>
    </security:session-management>    
</security:http>

<security:method-security-metadata-source id="securityMetadataSource">
        <security:protect method="com.services.CreateUserService.createUser" access="ROLE_ADMIN"/>
        <security:protect method="com.services.DeleteUser.deleteUser" access="ROLE_ADMIN"/>
</security:method-security-metadata-source>

<security:global-method-security authentication-manager-ref="authenticationManager" access-decision-manager-ref="accessDecisionManager" 
metadata-source-ref="securityMetadataSource" pre-post-annotations="disabled" secured-annotations="disabled" />

<bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <property name="loginFormUrl" value="/login.jsp"/>
</bean>

<bean id="myRoleVoter" class="com.interceptors.MyRoleVoter" />

<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager" >
    <property name="providers">
        <list>
            <ref local="daoAuthenticationProvider"/>
        </list>
    </property>
</bean> 

<bean id="accessDecisionManager" class="com.interceptors.MyAccessDecisionManager"  p:allowIfAllAbstainDecisions="false" >
    <property name="decisionVoters">
        <list>
            <ref local="myRoleVoter"/>
        </list>
    </property> 
</bean>


<bean id="methodSecurity" class="org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
        <property name="securityMetadataSource" ref="securityMetadataSource" />
</bean> 

認証部分は完全に正常に機能しています。ただし、私の MethodSecurityInterceptor は呼び出されないため、AccessDecisionManager または RoleVoter も呼び出されません。

最初の行に accessDecisionManager の参照を追加すると、認証レイヤーが機能しなくなります。すべてのリクエストは、ユーザーを匿名として AccessDecisionManager に渡されます。

<security:http security="none" pattern="/login.jsp" />

<security:http auto-config='true' authentication-manager-ref="authenticationManager" access-decision-manager-ref="accessDecisionManager" use-expressions="true" request-matcher="ant" create-session="always"
    entry-point-ref="authenticationEntryPoint" >

TINY 構成が欠落していることはわかっていますが、ドキュメントのどこにもその構成が見つかりません。

4

3 に答える 3

1

私は解決策を見つけました。2つの認証マネージャーと1つのアクセス決定マネージャーを定義する必要があります。1つの認証マネージャーが私のルートコンテキストに入り、グローバルメソッドセキュリティによってフォームログイン認証メカニズムを作成するために使用されます。

もう一方の認証マネージャーとアクセス決定マネージャーは、サービスコンテキストで使用され、カスタムメソッドのセキュリティインターセプターを作成するために使用されます。

applicationContext-Security.xml

<!-- The authentication manager responsible for authenticating the users -->
<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager" >
    <property name="providers">
        <list>
            <ref local="daoAuthenticationProvider"/>
        </list>
    </property>
</bean> 

サービスのコンテキストファイル。 service.security.xml

    <!--we need a separate authentication manager for method security -->
    <bean id="methodAuthenticationManager" class="org.springframework.security.authentication.ProviderManager" >
        <property name="providers">
            <list>
                <ref local="daoAuthenticationProvider"/>
            </list>
        </property>
    </bean> 

    <!--we need a separate accessDecisionManager for method security -->
    <bean id="methodAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased" >
        <property name="decisionVoters">
            <list>
                <ref local="myRoleVoter"/> <!-- the voter will decide weather methodInvocation is allowed or not -->
            </list>
        </property> 
    </bean>

    <!-- The Method Security Interceptor to intercept all the calls to methods -->
    <bean id="methodSecurityInterceptor" class="org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor">
        <property name="authenticationManager" ref="methodAuthenticationManager"/>
        <property name="accessDecisionManager" ref="methodAccessDecisionManager"/>
        <property name="securityMetadataSource" ref="swiftSecurityMethodMetadataSource" />
    </bean>


<security:method-security-metadata-source id="securityMetadataSource">
    <security:protect method="fullyQualifiedMethod" access="Administrator"/>
</security:method-security-metadata-source>

<security:global-method-security authentication-manager-ref="methodAuthenticationManager" access-decision-manager-ref="methodAccessDecisionManager" 
    metadata-source-ref="swiftSecurityMethodMetadataSource" jsr250-annotations="disabled" secured-annotations="disabled"/>
于 2012-08-23T11:07:16.833 に答える
1

おそらく、アプリケーションのルート コンテキストで MethodSecurityInterceptor を宣言しており、それがサーブレット コンテキストの Bean に対して機能することを期待しています。

サーブレット コンテキストで作業する場合global-method-securityは、サーブレット xml 構成で明示的に宣言する必要があります。

間違ったコンテキストで AOP インターセプターを宣言するのは非常によくある間違いです。そのため、サーブレット コンテキストでサービス レイヤー Bean が作成されていないことを確認してください (たとえば、自動スキャンによって)。

于 2012-08-06T12:01:47.100 に答える
0

MethodSecurityInterceptorAOPが呼び出されないもう 1 つの一般的な理由-cglibバイト コード操作のミスまたは類似。

したがって、使用されるだけなので、プライベートメソッドjava.lang.reflect.Proxyをプロキシすることはできません。メソッドを公開するだけで、すべて問題ありません。@Secured

于 2014-12-15T18:27:01.417 に答える