1

我有一个带有 keytab 文件的弹簧安全 kerberos 设置。完成文件上传操作后,我收到连接重置错误。仅当文件大小大于 2MB 时才会发生这种情况。关闭spring security时,我可以上传大于2MB的文件。

我对基于 SPNEGO 的身份验证的理解如下。

  1. 从浏览器发送 Ajax 请求
  2. 服务器检查标头中的令牌,如果找不到,则发送 401 协商
  3. 客户端使用 kerberos 令牌重新发送请求
  4. 服务器使用 keytab 解密令牌并很高兴允许进一步通信

一个典型的请求将在协商重定向后在标头中发送 kerberos 身份验证令牌。这些失败的请求在标头中没有令牌,这意味着协商阶段没有开始。

是否需要为文件上传设置或删除任何其他标题?2mb的限制在哪里设置?我看到 Jboss 有一个 max-post 参数,但是当安全性被删除时,上传工作正常。

环境:Jboss EAP 6.4.16(10 个无状态服务器),JVM 1.7,RHEL 6。前面没有 Web 服务器。

失败请求的标头 -

Provisional headers are shown
Accept:application/json, text/javascript, */*; q=0.01
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryeb4P029q02XzceLA
Origin:xxxxx
Referer:http://xxxxxxxxxxxxxxx.html?xxxxxxxxxxxx
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/43.0.2357.130 Safari/537.36
X-Requested-With:XMLHttpRequest
------WebKitFormBoundaryeb4P029q02XzceLA
Content-Disposition: form-data; name="entry"; filename="test.pdf"
Content-Type: application/pdf
------WebKitFormBoundaryeb4P029q02XzceLA--

代码部分:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Value("${auth.keytab.url}")
    private Resource keyTabLocation;

    private static final String SECURITY_ACCESS_ROLE = "isFullyAuthenticated() and hasRole('SOME_ROLE')";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Please dont format this section
        // Some eclipse version may not support below formatter off.
        // @formatter:off
        HttpSecurity httpSecurity =
                //default response headers disabled to aid xframe
                http.headers().disable().csrf().disable()
                // csrf disabled to facilitate non-browser calls
                    .httpBasic().authenticationEntryPoint(spnegoEntryPoint())
                .and()
                    .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                    .authorizeRequests().antMatchers("/**")
                    .access(SECURITY_ACCESS_ROLE).anyRequest().authenticated()
                .and();

            httpSecurity
                    .addFilterBefore(
                            spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
                            BasicAuthenticationFilter.class);

        // @formatter:on
        // Please dont format this section
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(ignoreSecurity.split(","));
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.authenticationProvider(kerberosServiceAuthenticationProvider());
    }

    @Bean(name = "authenticationManager")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    @Scope("prototype")
    public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
        SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
        ticketValidator.setServicePrincipal(servicePrincipal);
        ticketValidator.setKeyTabLocation(keyTabLocation);
        ticketValidator.setDebug(true);
        return ticketValidator;
    }

    @Bean
    @Scope("prototype")
    public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
        KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
        provider.setTicketValidator(ticketValidator);
        provider.setUserDetailsService(kerberosUserDetailsService());
        return provider;
    }

    @Bean
    public UserDetailsService kerberosUserDetailsService() {
        return new KerberosUserDetailsService();
    }

    @Bean
    public UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> userDetailsByNameServiceWrapper() {
        UserDetailsService userDetailsService = cookieUserDetailsService();
        return new UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken>(userDetailsService);
    }

    @Bean
    public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
            AuthenticationManager authenticationManager) {
        SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
        filter.setAuthenticationManager(authenticationManager);
        return filter;
    }

    @Bean
    public SpnegoEntryPoint spnegoEntryPoint() {
        return new SpnegoEntryPoint();
    }
}
4

0 回答 0