【问题标题】:Spring 4 Security configuration runs but not activeSpring 4 安全配置运行但未激活
【发布时间】:2017-02-04 18:24:55
【问题描述】:

我对 Spring 很陌生,如果我的问题听起来很愚蠢,我很抱歉。

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

我现在一直在关注 quite a few tutorialsreference 文档,但它们似乎都表示相同的东西,所以很明显我一定遗漏了一些东西。

我想要定义一个简单的配置,其中默认情况下每个请求都在 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

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

【问题讨论】:

    标签: java spring spring-security spring-4


    【解决方案1】:

    你必须注册springSecurityFilterChain,见Spring Security Reference

    下一步是在战争中注册springSecurityFilterChain。这可以在 Java 配置中通过 Spring 的 WebApplicationInitializer 支持在 Servlet 3.0+ 环境中完成。毫不奇怪,Spring Security 提供了一个基类AbstractSecurityWebApplicationInitializer,它将确保为您注册 springSecurityFilterChain。我们使用 AbstractSecurityWebApplicationInitializer 的方式会有所不同,具体取决于我们是否已经在使用 Spring,或者 Spring Security 是否是我们应用程序中唯一的 Spring 组件。

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

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

    另见:

    【讨论】:

    • 非常感谢!根据之前提供的示例,我不得不将过滤器添加到restHandler。
    猜你喜欢
    • 1970-01-01
    • 2021-04-23
    • 2017-02-05
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 2013-10-22
    相关资源
    最近更新 更多