Spring @Secured and @PreAuthorize have no effect i

2019-06-13 08:12发布

问题:

I created a Application Spring component with two secured methods:

@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" );
    }
}

I call run() method on that bean, which I take from Spring XML context:

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

Nothings happen - methods are called normally even if there is no authentication and SecurityContextHolder.getContext().getAuthentication() returns null

My Spring 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"/>

I use Maven dependencies for Spring 3.2.4

回答1:

2 Things

Spring uses a proxy based solution for AOP. Which means only external method calls are intercepted, you are making internal method calls and those bypass the proxy.

Second make sure you are using class based proxies (you aren't using interfaces so JDK Dynamic Proxies won't work). Add proxy-target-class="true" to your <global-method-security .. /> element. Make sure you have cglib on your classpath as that is required for classbased proxies.