0

Application用两种安全方法创建了一个 Spring 组件:

@Component
public class Application {

    public void run() {
        onlyAdminMethod();
        onlyAdminMethod2();
    }

    @Secured( "ROLE_ADMIN" )
    public void onlyAdminMethod() {
        System.out.println( "Admin-only method called" );
    }

    @PreAuthorize( "hasRole('ROLE_ADMIN')" )
    public void onlyAdminMethod2() {
        System.out.println( "Admin-only method 2 called" );
    }
}

我在那个 bean 上调用run()方法,我从 Spring XML 上下文中获取:

ClassPathXmlApplicationContext context = 
     new ClassPathXmlApplicationContext("applicationContext.xml");  
context.getBean( Application.class).run();

什么都没有发生 -即使没有身份验证并SecurityContextHolder.getContext().getAuthentication()返回,方法也会正常调用null

我的春天 XML

<context:annotation-config />
<context:component-scan base-package="practice" />

<security:authentication-manager>
   <security:authentication-provider>
      <security:user-service>
         <security:user name="admin" password="stackoverflow" authorities="ROLE_USER,ROLE_ADMIN" />
      </security:user-service>
   </security:authentication-provider>
</security:authentication-manager>

<security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled"/>

我使用 Maven 依赖项Spring 3.2.4

4

1 回答 1

3

2 件事

Spring 使用基于代理的 AOP 解决方案。这意味着只有外部方法调用被拦截,您正在进行内部方法调用并且那些绕过代理。

其次,确保您使用的是基于类的代理(您没有使用接口,因此 JDK 动态代理不起作用)。添加proxy-target-class="true"到您的<global-method-security .. />元素。确保您的类路径中有 cglib,因为这是基于类的代理所必需的。

于 2013-10-17T08:33:38.433 回答