CORS 起源问题 - Spring Boot 和 Angular 4
Posted
技术标签:
【中文标题】CORS 起源问题 - Spring Boot 和 Angular 4【英文标题】:CORS Origin issue - Spring Boot & Angular 4 【发布时间】:2018-10-30 08:30:22 【问题描述】:我目前正在处理 Angular 4 FrontEnd App 和 Spring Boot Backend App 之间的 JWT 身份验证,服务器端的一切工作正常,我在身份验证级别遇到的问题如下。
这发生在我获得登录请求已成功处理的 200 OK 状态后,如下图所示。
在我用于安全应用程序和登录处理的配置下方。
public class JWTAuthorizationFiler extends OncePerRequestFilter
@SuppressWarnings("unchecked")
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, "
+ "Access-Control-Request-Method, Access-Control-Request-Headers, authorization");
response.addHeader("Access-Control-Expose-Headers",
"Access-Control-Allow-Origin, Access-Control-Allow-Credentials, authorization");
if (request.getMethod().equals("OPTIONS"))
response.setStatus(HttpServletResponse.SC_OK);
String jwt = request.getHeader(SecurityConstants.HEADER_STRING);
if (jwt == null || !jwt.startsWith(SecurityConstants.TOKEN_PREFIX))
filterChain.doFilter(request, response);
return;
Claims claims = Jwts.parser().setSigningKey(SecurityConstants.SECRET)
.parseClaimsJws(jwt.replace(SecurityConstants.TOKEN_PREFIX, "")).getBody();
String username = claims.getSubject();
ArrayList<Map<String, String>> roles = (ArrayList<Map<String, String>>) claims.get("roles");
Collection<GrantedAuthority> authorities = new ArrayList<>();
roles.forEach(r ->
authorities.add(new SimpleGrantedAuthority(r.get("authority")));
);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
null, authorities);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
filterChain.doFilter(request, response);
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private BCryptPasswordEncoder bCyptPasswordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(userDetailsService).passwordEncoder(bCyptPasswordEncoder);
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// http.formLogin();
http.authorizeRequests().antMatchers("/login/**", "/register/**", "/paramsApi/**").permitAll();
http.authorizeRequests().antMatchers(HttpMethod.POST, "/studentResource/**").hasAuthority("ADMIN");
http.authorizeRequests().antMatchers(HttpMethod.GET, "/studentResource/**").hasAuthority("ADMIN");
http.authorizeRequests().anyRequest().authenticated();
http.addFilter(new JWTAuthenticationFilter(authenticationManager()));
http.addFilterBefore(new JWTAuthorizationFiler(), UsernamePasswordAuthenticationFilter.class);
我认为 JWTAuthorizationFilter.java 是这个问题的主要原因,非常感谢任何解决这个问题的方法。
【问题讨论】:
【参考方案1】:在SecurityConfig
类的configure
方法中,您必须像这样启用 CORS
http.cors().and() ...//continue the rest of the configuration..
通过定义http.cors()
,它将默认使用名称为 bean
corsConfigurationSource 在这种情况下,您还必须在 SecurityConfig
类中定义一个 bean,它将保存 CORS 配置。
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://localhost:4200"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
您可以使用 WebMvcConfigureAdapter
类来启用 CORS
还有
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/api/**")
.allowedOrigins("your url or just add * ")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
可能不需要完整的配置,只需删除不必要的方法,如 allowedMethods、allowedHeaders 和暴露的Headers 。
欲了解更多信息,请通过 https://spring.io/blog/2015/06/08/cors-support-in-spring-framework & https://docs.spring.io/spring-security/site/docs/current/reference/html/cors.html
【讨论】:
以上是关于CORS 起源问题 - Spring Boot 和 Angular 4的主要内容,如果未能解决你的问题,请参考以下文章