Spring 4 安全配置运行但未激活

Spring 4 Security configuration runs but not active

我是 Spring 的新手,如果我的问题听起来很愚蠢,我深表歉意。

我正在尝试将基本 HTTP 身份验证添加到基于 Spring 的 REST API。

我目前一直在关注 quite a few tutorials and reference 文档,但它们似乎都表明了同一件事,所以很明显我一定遗漏了一些东西。

我想要的是定义一个简单的配置,其中 默认情况下每个请求都在 HTTP Auth 之后,但是我们可以根据需要使用 @PreAuthorize 或通过修改HttpSecurity 配置.

我定义了一个非常简单的配置:

@Configuration
@EnableWebMvc
@EnableWebSecurity
@ComponentScan(basePackages = "com.app.rest")
public class RESTConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().hasAnyRole("USER")
                .and()
                .httpBasic();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
    }
}

然后我有一个非常简单的控制器(没有服务,没什么特别的)。

这是一个非常基本的概述:

@RestController
@RequestMapping("/images")
public class ImagesController {

    @JsonView(View.Basic.class)
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ObjectXvo getImageByID(@PathVariable String id) throws IOException {

        ObjectXvo result = doThings();
        return result;
    }
}

与所有在线教程相比,唯一明显的区别是我们加载此 API 的方式。因为我们已经有一个 Jetty 容器 运行 其他东西,所以我们决定重用它而不是像大多数在线使用的那样使用 WebAppInitializer

这里摘录了 REST API 的定义:

// Creating REST Servlet
ServletContextHandler restHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
restHandler.setErrorHandler(null);
restHandler.setContextPath("/rest");

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.app.test");
WebApplicationContext webAppContext = context;

DispatcherServlet dispatcherServlet = new DispatcherServlet(webAppContext);
ServletHolder springServletHolder = new ServletHolder("REST dispatcher", dispatcherServlet);
restHandler.addServlet(springServletHolder, "/");
restHandler.addEventListener(new ContextLoaderListener(webAppContext));

// Creating handler collection
ContextHandlerCollection handlerCollection = new ContextHandlerCollection();
handlerCollection.addHandler(anotherHandler);
handlerCollection.addHandler(restHandler);
handlerCollection.addHandler(yetAnotherHandler);

// Setting server context
server.setHandler(handlerCollection);

问题是,当 运行 应用程序时,我仍然可以访问所有 URL,就像我没有设置任何安全方案一样。 调试应用程序时,我可以看到 RESTConfiguration 正在处理,因为我的配置方法中的断点肯定会被命中。

我们已经决定尽可能避免使用 XML 文件,因为我们认为到目前为止注释更好。

任何人都可以指出正确的方向来说明为什么这个安全配置没有被激活吗?

编辑:

不确定这有多相关,但如果我尝试将 @PreAuthorize 添加到 REST 方法,我会收到以下错误:

HTTP ERROR: 500

Problem accessing /rest/images/I147. Reason:

    An Authentication object was not found in the SecurityContext

互联网上有很多关于如何解决这个问题的信息,但我想知道这是否不相关。

您必须注册 springSecurityFilterChain,请参阅 Spring Security Reference:

The next step is to register the springSecurityFilterChain with the war. This can be done in Java Configuration with Spring’s WebApplicationInitializer support in a Servlet 3.0+ environment. Not suprisingly, Spring Security provides a base class AbstractSecurityWebApplicationInitializer that will ensure the springSecurityFilterChain gets registered for you. The way in which we use AbstractSecurityWebApplicationInitializer differs depending on if we are already using Spring or if Spring Security is the only Spring component in our application.

如果您不使用 AbstractSecurityWebApplicationInitializer,则必须手动注册 springSecurityFilterChain

webAppContext.getServletContext()
    .addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
    .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC), false, "/*");

另请参阅: