我正在尝试使用Spring Security 3.2设置我的Spring服务器,以便能够执行ajax登录请求。
我关注了Spring Security 3.2视频和几篇帖子,但问题是我越来越
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:9000' is therefore not allowed access.
对于登录请求(请参见下文)。
我已经创建了一个CORSFilter设置,并且可以通过将适当的标头添加到响应中来访问系统中不受保护的资源。
我的猜测是我没有将CORSFilter它添加到安全过滤器链中,否则可能太晚了。任何想法将不胜感激。
CORSFilter
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 { }
SecurityConfig:
对 / api / users的 请求运行良好,并添加了Access-Control-Allow标头。我禁用了csrf和标头只是为了确保不是这种情况
@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。
所以最终版本是:
@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();
并从中删除CORSFilter WebAppInitializer