如何在 Spring Security 3.2 中有问题地设置 Access-Control-Allow-Origin 过滤器 [英] How to setup Access-Control-Allow-Origin filter problematically in Spring Security 3.2

查看:31
本文介绍了如何在 Spring Security 3.2 中有问题地设置 Access-Control-Allow-Origin 过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Spring Security 3.2 设置我的 Spring 服务器,以便能够执行 ajax 登录请求.

I am trying to setup my Spring server with Spring Security 3.2 to be able to do an ajax login request.

我关注了 Spring Security 3.2 视频和一些帖子,但问题是我得到了 >

I followed the Spring Security 3.2 video and couple of posts but the issue is that I am getting

 No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:9000' is therefore not allowed access. 

对于登录请求(见下文).

For the login requests (see below).

我已经创建了一个 CORSFilter 设置,我可以访问系统中不受保护的资源,并将适当的标头添加到响应中.

I have created a CORSFilter setup and I can access the unprotected resources in my system with the appropriate headers being added to the response.

我的猜测是我没有将 CORSFilter 添加到安全过滤器链中,否则在链中可能为时已晚.任何想法将不胜感激.

My guess is that I am not adding the CORSFilter to security filter chain or it may be too late far in the chain. Any idea will be appreciated.

WebAppInitializer

public class WebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) {
        WebApplicationContext rootContext = createRootContext(servletContext);

        configureSpringMvc(servletContext, rootContext);

        FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", CORSFilter.class);
        corsFilter.addMappingForUrlPatterns(null, false, "/*");
    }

    private WebApplicationContext createRootContext(ServletContext servletContext) {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

        rootContext.register(SecurityConfig.class, PersistenceConfig.class, CoreConfig.class);

        servletContext.addListener(new ContextLoaderListener(rootContext));
        servletContext.setInitParameter("defaultHtmlEscape", "true");

        return rootContext;
    }


    private void configureSpringMvc(ServletContext servletContext, WebApplicationContext rootContext) {
        AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
        mvcContext.register(MVCConfig.class);

        mvcContext.setParent(rootContext);
        ServletRegistration.Dynamic appServlet = servletContext.addServlet(
                "webservice", new DispatcherServlet(mvcContext));
        appServlet.setLoadOnStartup(1);
        Set<String> mappingConflicts = appServlet.addMapping("/api/*");

        if (!mappingConflicts.isEmpty()) {
            for (String s : mappingConflicts) {
                LOG.error("Mapping conflict: " + s);
            }
            throw new IllegalStateException(
                    "'webservice' cannot be mapped to '/'");
        }
    }

SecurityWebAppInitializer:

public class SecurityWebAppInitializer extends AbstractSecurityWebApplicationInitializer {
}

安全配置:

/api/users 的请求 - 运行良好,并且添加了 Access-Control-Allow 标头.我禁用了 csrf 和标题只是为了确保不是这种情况

Requests to /api/users - work well and the Access-Control-Allow headers are added . I disabled csrf and headers just to make sure this is not the case

@EnableWebMvcSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .headers().disable()                
            .authorizeRequests()
                    .antMatchers("/api/users/**").permitAll()
                    .anyRequest().authenticated()
                    .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

CORFilter:

@Component
public class CORSFilter implements Filter{
    static Logger logger = LoggerFactory.getLogger(CORSFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        chain.doFilter(request, response);
    }

    public void destroy() {}
}

登录请求:

Request URL:http://localhost:8080/devstage-1.0/login
Request Headers CAUTION: Provisional headers are shown.
Accept:application/json, text/plain, */*
Cache-Control:no-cache
Content-Type:application/x-www-form-urlencoded
Origin:http://127.0.0.1:9000
Pragma:no-cache
Referer:http://127.0.0.1:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Form Dataview sourceview URL encoded
username:user
password:password

推荐答案

我所缺少的是 AddFilterBefore 当配置安全配置.

All I was missing was AddFilterBefore when configuring the security configuration.

所以最终版本是:

@EnableWebMvcSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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


  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http
          .addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class)

          .formLogin()
              .loginPage("/login")
              .and()
          .authorizeRequests()
              .anyRequest().authenticated();

并从 WebAppInitializer

这篇关于如何在 Spring Security 3.2 中有问题地设置 Access-Control-Allow-Origin 过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆