복붙노트

[SPRING] @Secured 주석은 Autoproxy로 AspectJ 모드에서 작동하지 않는다.

SPRING

@Secured 주석은 Autoproxy로 AspectJ 모드에서 작동하지 않는다.

내 Spring MVC 응용 프로그램이 Spring @Secured 주석과 AspectJ 자동 프록시로 잘 작동하도록하려하지만 proxying 또는 @Secured 주석을 인식하지 못하는 것 같습니다. 나는 이런 컨트롤러를 가지고있다 :

@Controller
@RequestMapping("/")
public class ApplicationController {

    private ApplicationFactory applicationFactory;

    @Inject
    public ApplicationController(ApplicationFactory applicationFactory) {
        super();
        this.applicationFactory = applicationFactory;
    }

    @Secured("ROLE_USER")
    @ResponseBody
    @RequestMapping(method = GET)
    public Application getApplicationInfo() {
        return applicationFactory.buildApplication(this);
    }

}

그리고 봄 보안 XML은 다음과 같습니다.

암호:

  <security:global-method-security secured-annotations="enabled" mode="aspectj" proxy-target-class="true" />

  <security:http auto-config="true" use-expressions="true">
    <security:http-basic/>
  </security:http>

위의 내용은 다음과 같이 no-xml Spring @Configuration 구성 요소에 의해로드됩니다.

@Configuration
@ComponentScan(basePackages = {"com.example"})
@EnableWebMvc
@ImportResource("classpath:security.xml")
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {

}

Servlet 3.0 WebApplicationInitializer를 사용하여로드됩니다.

public class SpringMvcInitializer implements WebApplicationInitializer {

    private final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();

    public void onStartup(ServletContext servletContext) throws ServletException {
        context.register(ApplicationConfiguration.class);

        servletContext.addListener(new ContextLoaderListener(context));
        servletContext.addListener(new Log4jConfigListener());

        final DelegatingFilterProxy proxy = new DelegatingFilterProxy("springSecurityFilterChain", context);
        FilterRegistration.Dynamic filter = servletContext.addFilter("securityFilter", proxy);
        filter.addMappingForUrlPatterns(EnumSet.of(REQUEST), false, "/*");

        final DispatcherServlet servlet = new DispatcherServlet(context);
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", servlet);
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/*");
    }

}

그러나 스프링 시큐리티는 주석을 탐지하지 못하고 있으며 위의 보안 된 엔드 포인트를 인증받지 않고 계속 사용할 수 있습니다. Spring Security FAQ에 따르면 아마도 요소가 잘못된 응용 프로그램 컨텍스트에로드되기 때문에 가능하지만 위의 no-xml Spring 구성을 사용하여이를 보장하는 방법을 알지 못합니다.

내가 놓친 게 있니? @EnableAspectJAutoProxy (proxyTargetClass = true)를 내 응용 프로그램 구성에 추가하려고 시도했지만 그 중 하나도 도움이되지 않았습니다. 어쨌든 런타임 짜기가 있어야합니까? 아니면 응용 프로그램에 주석 기반 보안을 사용하기 위해 컴파일 타임을 사용해야합니다.

해결법

  1. ==============================

    1.Spring과 함께 AOP를 사용할 때 두 가지 AOP 구현 중 하나를 선택할 수 있습니다.

    Spring과 함께 AOP를 사용할 때 두 가지 AOP 구현 중 하나를 선택할 수 있습니다.

    mode = "aspectj"는 Spring에게 AOP 구현을 위해 AspectJ를 사용하도록 지시한다. 따라서 여러분의 경우에 위빙하지 않으면 보안 측면이 작동하지 않는다.

    "AspectJ 자동 프록시"라는 용어는 AspectJ를 AOP 구현으로 사용하는 것과는 아무런 관련이 없다. 이것은 AspectJ API (구현보다는)를 Spring AOP와 함께 사용할 수있게 해주는 기능이다.

    따라서 컨트롤러가 Spring 빈이므로 Spring AOP 구현을 사용할 수 있으므로 mode = "aspectj"를 제거해야합니다. 또한 컨트롤러에는 인수없는 생성자가 있어야합니다. 이는 Spring AOP의 한계 중 하나입니다.

  2. ==============================

    2.@ axtavt의 대답을 좀 더 확장하기 위해 global-method-security의 mode = "aspectj"옵션은 특히 코드가 spring-security-aspects 모듈의 AnnotationSecurityAspect로 짜여져 있어야합니다.

    @ axtavt의 대답을 좀 더 확장하기 위해 global-method-security의 mode = "aspectj"옵션은 특히 코드가 spring-security-aspects 모듈의 AnnotationSecurityAspect로 짜여져 있어야합니다.

    그것을 사용하는 몇 가지 샘플 코드가 있습니다. 보안 Bean과 일부 Junit 테스트로만 구성되어 있지만 코드는 AspectJ 컴파일러로 컴파일됩니다. 또한 응용 프로그램 컨텍스트는 네임 스페이스 지원이 추가되기 전에 필요한 것 (주석 처리 된 bean)과 얼마나 간단하게 비교되는지 보여줍니다.

  3. from https://stackoverflow.com/questions/11400503/secured-annotations-not-working-in-aspectj-mode-with-autoproxy by cc-by-sa and MIT license