Spring 安全性 4.x 用于使用 Hawtio 进行基本身份验证的 JavaConfig

Spring Security 4.x JavaConfig for Basic authentication with Hawtio

我正在尝试将 Hawtio (1.4.64) 连接到 Tomcat 中的 Spring 应用程序中的 Jolokia 代理 (1.3.3) 运行 7.

最近升级到 Spring Security (4.0.3) 之后,hawtio 停止了正确的身份验证(使用基本身份验证),我们被踢回登录页面,类似于 issue #1975 。与那个问题不同的是,我们只使用 Jolokia 代理而不是在我们的应用程序中包含 hawtio(并且我们没有使用 Spring Boot)。

检查 Spring 调试日志后,AnonymousAuthenticationFilter 似乎在应用 BasicAuthenticationFilter 之前将用户设置为 "anonymous"。所以我调整了安全配置并禁用了所有默认值,留下以下内容:

@Configuration
@Order(2)
public static class JolokiaSecurityConfig extends WebSecurityConfigurerAdapter {

    public JolokiaSecurityConfig() {
        super(true); // disable defaults
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .requestMatchers().antMatchers("/jolokia/**")
            .and().authorizeRequests().antMatchers("/jolokia/**").hasAuthority(BaseRoles.DEVELOPER).and().httpBasic();
    }
}

现在,当我登录到 Hawtio 时,我在 Hawtio 控制台中收到一个错误,其中包括我的 Tomcat7 服务器的一些输出:HTTP 状态 500 - 在 SecurityContext[=15 中找不到身份验证对象=]

堆栈跟踪:

Jul 06, 2016 12:43:14 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [jolokia-agent] in context with path [/foobar] threw exception
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:378)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:222)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)

...

知道为什么基本身份验证不再有效吗?感谢您的帮助!

我们通过覆盖异常处理以再次调用 BasicAuthenticationEntryPoint 解决了这个问题:

@Configuration
@Order(2)
public static class JolokiaSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String REALM = "our admin services";
    private static final String JOLOKIA_URL_PATTERN = "/jolokia/**";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        BasicAuthenticationEntryPoint authenticationEntryPoint = new BasicAuthenticationEntryPoint();
        authenticationEntryPoint.setRealmName(REALM);
        http
            .csrf().disable()
            .requestMatchers().antMatchers(JOLOKIA_URL_PATTERN)
            .and().authorizeRequests().antMatchers(JOLOKIA_URL_PATTERN).hasAuthority(BaseRoles.DEVELOPER)
            .and().httpBasic().realmName(REALM)
            .and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
    }
}