2

SpringMVCアプリをSpring@SecuredアノテーションとAspectJ自動プロキシでうまく動作させようとしていますが、@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-xmlSpring@Configurationコンポーネントによってロードされています。

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

}

これは、サーブレット3.0WebApplicationInitializerを使用してロードされます。

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はアノテーションを検出しておらず、許可されていなくても上記のセキュリティで保護されたエンドポイントを使用できます。Spring Security FAQによると、これはおそらく<global-method-security>要素が間違ったアプリケーションコンテキストにロードされているためですが、上記のno-xmlSpring構成を使用してこれを確認する方法がわかりません。

私は何かが足りないのですか?@EnableAspectJAutoProxy(proxyTargetClass = true)をアプリケーション構成に追加しようとしましたが、それも役に立ちませんでした。とにかくランタイムウィービングを行う必要がありますか、それともアプリケーションのアノテーションベースのセキュリティを有効にするためにコンパイルタイムウィービングを使用する必要がありますか?

4

2 に答える 2

6

Spring で AOP を使用する場合、AOP の 2 つの実装から選択できます。

  • Spring AOP 実装は織り込みを必要としませんが、Spring によって管理される Bean にのみ適用され、いくつかの制限があります

  • AspectJ AOP 実装はすべてのオブジェクトで機能し、Spring AOP の制限はありませんが、コンパイル時またはロード時のウィービングが必要です

mode="aspectj"AOP実装にAspectJを使用するようSpringに指示するため、セキュリティの側面は、あなたのケースで織り込まないと機能しません。

「AspectJ 自動プロキシ」という用語は、AspectJ を AOP 実装として使用することとは関係ありません。Spring AOP で AspectJ API (実装ではなく) を使用できるようにする機能です。

したがって、コントローラーはSpring Beanであるため、Spring AOP実装を使用できます。したがって、を削除する必要がありますmode="aspectj"。また、コントローラーには引数のないコンストラクターが必要であることに注意してください。これは、Spring AOP の制限の 1 つです。

于 2012-07-09T18:45:32.863 に答える
4

@axtavt の回答を少し拡張するには、オプションのmode="aspectj"オプションでglobal-method-securityは、コードがモジュールの と織り込まれている必要がAnnotationSecurityAspectありspring-security-aspectsます。

使用方法を示すサンプルコードがいくつかあります。セキュア Bean といくつかの Junit テストで構成されているだけですが、コードは AspectJ コンパイラでコンパイルされています。また、アプリケーション コンテキストは、名前空間サポートが追加される前に必要だったもの (コメント アウトされた Bean) と比較して、それがいかに単純であるかを示しています。

于 2012-07-13T17:00:23.797 に答える