【问题标题】:Disable Redirect by Spring Security in Jersey Spring Boot Application在 Jersey Spring Boot 应用程序中禁用 Spring Security 重定向
【发布时间】:2015-08-17 13:48:39
【问题描述】:

我正在拔头发。该环境是通过 Spring Boot 配置的 JAXRS(使用 Jersey)Restful 应用程序。我正在开发一个与微服务通信的编排层。编排层使用 RestTemplate 执行对微服务的调用。

由于某种原因,当编排服务返回错误级别的状态码时,Spring Security 会尝试发布到http://localhost:65448/error。我不知道是谁在做这件事。我已经打开了日志记录,跟踪了代码,搜索了互联网,并阅读了所有文档......我无法确定哪个类正在尝试这样做。我无法阻止它。

这是我用于安全位的 Spring 配置(groovy):

@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Inject
    private UserService userService

    @Inject
    private StatelessAuthenticationFilter statelessAuthenticationFilter

    void configure(WebSecurity web) throws Exception {

    }

    void configure(HttpSecurity http) throws Exception {
        http
                .anonymous().and()
              //  .servletApi().and()
                .headers().cacheControl().and()
                .exceptionHandling().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .rememberMe().disable()
                .csrf().disable()
                .formLogin().disable()
                .httpBasic().disable()
                .jee().disable()
                .logout().disable()
                //.openidLogin().disable()
                .authorizeRequests()
                .filterSecurityInterceptorOncePerRequest(true)

        // Allow anonymous logins
                .antMatchers('/security/authc').permitAll()

        // All other request need to be authenticated
                .anyRequest().authenticated().and()

        // Custom Token based authentication based on the header previously given to the client
               .addFilterAfter(statelessAuthenticationFilter, BasicAuthenticationFilter)
    }

    void configure(AuthenticationManagerBuilder auth) {
        auth
                .userDetailsService(userService)
                .passwordEncoder(passwordEncoder())
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        new BCryptPasswordEncoder()
    }

    @Bean
    AuthenticationManager authenticationManagerBean() {
        super.authenticationManagerBean()
    }

}

测试代码通过将 Authorization 标头发布到 authc 端点来执行简单的基于 rest 的身份验证。除非编排服务返回错误级别的状态代码,否则这将按预期工作。

这是相关的日志记录:

[2015-06-03 07:07:15.621] boot - 47784  INFO [qtp1012776440-21] --- LoggingFilter: 1 * Server has received a request on thread qtp1012776440-21
1 > POST http://localhost:65448/security/authc
1 > Accept: */*
1 > Accept-Encoding: gzip,deflate
1 > Authorization: bm90ZXhpc3RzOnRlc3RwYXNz
1 > Connection: keep-alive
1 > Content-Length: 0
1 > Content-Type: application/x-www-form-urlencoded; charset=ISO-8859-1
1 > Host: localhost:65448
1 > User-Agent: Apache-HttpClient/4.2.1 (java 1.5)

[2015-06-03 07:07:15.753] boot - 47784  INFO [qtp1012776440-21] --- LoggingFilter: 1 * Server responded with a response on thread qtp1012776440-21
1 < 400

[2015-06-03 07:07:15.757] boot - 47784  INFO [qtp1012776440-21] --- LoggingFilter: 2 * Server has received a request on thread qtp1012776440-21
2 > POST http://localhost:65448/error
2 > Accept: */*
2 > Accept-Encoding: gzip,deflate
2 > Authorization: bm90ZXhpc3RzOnRlc3RwYXNz
2 > Connection: keep-alive
2 > Content-Length: 0
2 > Content-Type: application/x-www-form-urlencoded; charset=ISO-8859-1
2 > Host: localhost:65448
2 > User-Agent: Apache-HttpClient/4.2.1 (java 1.5)

[2015-06-03 07:07:15.781] boot - 47784  INFO [qtp1012776440-21] --- LoggingFilter: 2 * Server responded with a response on thread qtp1012776440-21
2 < 404
2 < Content-Type: application/json

HTTP/1.1 404 Not Found
Date: Wed, 03 Jun 2015 11:07:15 GMT
Pragma: no-cache
X-Application-Context: Test:test:0
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.2.9.v20150224)

在我把电脑扔出窗外之前请帮忙。

干杯

【问题讨论】:

  • 这似乎与用于与微服务对话的 RestTemplate 有关。这完全出乎意料。我在 restTemplate.getForEntity 调用之后直接添加了日志记录,它从不输出任何内容。为什么面向 REST 的客户端会在 40X/50X 状态下执行重定向?这不是特别安宁。
  • 没关系。之前的说法是不正确的。

标签: rest spring-security jax-rs spring-boot


【解决方案1】:

喂,

这是 Jetty 的默认行为,当服务器响应状态码 >=400(404 除外)并且响应没有实体时。您可以通过设置一个空的错误页面列表来“禁用”此行为

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {

    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            // On skippe la redirection /error realise
            container.setErrorPages(Sets.<ErrorPage> newConcurrentHashSet());
        }
    };
}

尽管有这种变通方法,服务器仍将使用 XML 正文发送真实的 http 状态(请参阅 ErrorHandler)

undertow 也是如此。

【讨论】:

  • 我切换到 tomcat 仍然出现这种情况。
【解决方案2】:

这是由ErrorMvcAutoConfiguration 引起的。如果您有自定义错误路径,您可以禁用它(通过注释 EnableAutoConfiguration 上的排除)或更改其路径,使用属性 error.path

【讨论】:

  • 遗憾的是,这没有效果。我通过:@EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration) 排除了它,但没有运气。
猜你喜欢
  • 2016-07-16
  • 2018-10-13
  • 2016-07-21
  • 2015-02-05
  • 2014-01-11
  • 2017-03-06
  • 2019-05-08
  • 2020-03-17
  • 2016-09-03
相关资源
最近更新 更多