温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Security框架中怎么使用CorsFilter解决前端跨域请求问题

发布时间:2021-11-16 10:22:52 来源:亿速云 阅读:252 作者:iii 栏目:开发技术

本篇内容主要讲解“Security框架中怎么使用CorsFilter解决前端跨域请求问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Security框架中怎么使用CorsFilter解决前端跨域请求问题”吧!

项目情况

最近做的pmdb项目是前后端分离的, 由于测试的时候是前端与后端联调,所以出现了跨域请求的问题。

浏览器默认会向后端发送一个Options方式的请求,根据后端的响应来判断后端支持哪些请求方式,支持才会真正的发送请求。

CORS介绍

CORS(Cross-Origin Resource Sharing 跨源资源共享),当一个请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。

在日常的项目开发时会不可避免的需要进行跨域操作,而在实际进行跨域请求时,经常会遇到类似 No 'Access-Control-Allow-Origin' header is present on the requested resource.这样的报错。

Security框架中怎么使用CorsFilter解决前端跨域请求问题

这样的错误,一般是由于CORS跨域验证机制设置不正确导致的。

解决方案

注释:本项目使用的是SprintBoot+Security+JWT+Swagger

第一步

新建CorsFilter,在过滤器中设置相关请求头

package com.handlecar.basf_pmdb_service.filter;  import org.springframework.web.filter.OncePerRequestFilter;  import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;   public class CorsFilter extends OncePerRequestFilter {  //public class CorsFilter implements Filter { //    static final String ORIGIN = "Origin";      protected void doFilterInternal(             HttpServletRequest request, HttpServletResponse response,             FilterChain filterChain) throws ServletException, IOException {  //        String origin = request.getHeader(ORIGIN);          response.setHeader("Access-Control-Allow-Origin", "*");//* or origin as u prefer         response.setHeader("Access-Control-Allow-Credentials", "true");         response.setHeader("Access-Control-Allow-Methods", "PUT, POST, GET, OPTIONS, DELETE");         response.setHeader("Access-Control-Max-Age", "3600"); //        response.setHeader("Access-Control-Allow-Headers", "content-type, authorization");         response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With, Authorization");         response.setHeader("XDomainRequestAllowed","1");         //使前端能够获取到         response.setHeader("Access-Control-Expose-Headers","download-status,download-filename,download-message");             if (request.getMethod().equals("OPTIONS")) //            response.setStatus(HttpServletResponse.SC_OK);             response.setStatus(HttpServletResponse.SC_NO_CONTENT);         else             filterChain.doFilter(request, response);       }   //    @Override //    public void doFilter(ServletRequest req, 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", "0"); // //        response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With, auth"); // //        response.setHeader("Access-Control-Allow-Credentials", "true"); // //        response.setHeader("XDomainRequestAllowed","1"); //        chain.doFilter(req, res); //    } // //    @Override //    public void destroy() { //    } // //    @Override //    public void init(FilterConfig arg0) throws ServletException { //    } }

注释:这里的Access-Control-Expose-Headers的请求头是为了使前端能够获得到后端在response中自定义的header,不设置的话,前端只能看到几个默认显示的header。我这里是在使用response导出Excel的时候将文件名和下载状态信息以自定义请求头的形式放在了response的header里。

第二步

在Security的配置文件中初始化CorsFilter的Bean

 @Bean     public CorsFilter corsFilter() throws Exception {         return new CorsFilter();     }
第三步

在Security的配置文件中添加Filter配置,和映射配置

.antMatchers(HttpMethod.OPTIONS,"/**").permitAll()                     // 除上面外的所有请求全部需要鉴权认证。 .and() 相当于标示一个标签的结束,之前相当于都是一个标签项下的内容                 .anyRequest().authenticated().and()                 .addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class)

附:该配置文件

package com.handlecar.basf_pmdb_service.conf; import com.handlecar.basf_pmdb_service.filter.CorsFilter; import com.handlecar.basf_pmdb_service.filter.JwtAuthenticationTokenFilter; import com.handlecar.basf_pmdb_service.security.JwtTokenUtil; import com.handlecar.basf_pmdb_service.security.CustomAuthenticationProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; //import com.allcom.security.JwtTokenUtil;   @Configuration //@EnableWebSecurity is used to enable Spring Security's web security support and provide the Spring MVC integration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter {         private final CustomAuthenticationProvider customAuthenticationProvider;       @Autowired     public WebSecurityConfig(CustomAuthenticationProvider customAuthenticationProvider) {         this.customAuthenticationProvider = customAuthenticationProvider;     }       @Override     protected void configure(AuthenticationManagerBuilder auth) {         auth.authenticationProvider(customAuthenticationProvider);     }       @Bean     public JwtTokenUtil jwtTokenUtil(){         return new JwtTokenUtil();     }       @Bean     public CorsFilter corsFilter() throws Exception {         return new CorsFilter();     }       @Bean     public JwtAuthenticationTokenFilter authenticationTokenFilterBean() {         return new JwtAuthenticationTokenFilter();     }       @Override     protected void configure(HttpSecurity httpSecurity) throws Exception {         httpSecurity                 // 由于使用的是JWT,我们这里不需要csrf,不用担心csrf攻击                 .csrf().disable()                 // 基于token,所以不需要session                 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()                  .authorizeRequests()                     //.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()                      // 允许对于网站静态资源的无授权访问                     .antMatchers(                         HttpMethod.GET,                         "/",                         "/*.html",                         "/favicon.ico",                         "/**/*.html",                         "/**/*.css",                         "/**/*.js",                         "/webjars/springfox-swagger-ui/images/**","/swagger-resources/configuration/*","/swagger-resources",//swagger请求                         "/v2/api-docs"                     ).permitAll()                     // 对于获取token的rest api要允许匿名访问                     .antMatchers("/pmdbservice/auth/**","/pmdbservice/keywords/export3").permitAll()                     .antMatchers(HttpMethod.OPTIONS,"/**").permitAll()                     // 除上面外的所有请求全部需要鉴权认证。 .and() 相当于标示一个标签的结束,之前相当于都是一个标签项下的内容                 .anyRequest().authenticated().and()                 .addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class)                 .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);           // 禁用缓存         httpSecurity.headers().cacheControl();     }  }

到此,相信大家对“Security框架中怎么使用CorsFilter解决前端跨域请求问题”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI