Java 否';访问控制允许原点';标头出现在angular 9和spring boot 2中请求的资源上

Java 否';访问控制允许原点';标头出现在angular 9和spring boot 2中请求的资源上,java,angular,spring,spring-boot,spring-security,Java,Angular,Spring,Spring Boot,Spring Security,我在spring引导应用程序中添加了spring安全性,并且我有一些api端点,无论用户是否登录,都需要调用这些端点(我的意思是,这些是我需要在前端检索数据的其余端点) 因此,我将其配置为: @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true) public class WebSecurityConfig extends WebSe

我在spring引导应用程序中添加了spring安全性,并且我有一些api端点,无论用户是否登录,都需要调用这些端点(我的意思是,这些是我需要在前端检索数据的其余端点)

因此,我将其配置为:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Autowired
    private UserDetailsService customUserDetailsService;
 
 
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
 
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
         .userDetailsService(customUserDetailsService)
         .passwordEncoder(passwordEncoder());
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
           http.csrf().
           disable()
               .authorizeRequests()
               .antMatchers(HttpMethod.OPTIONS, "/**")
               .permitAll()
              .antMatchers("/books").permitAll()
            .antMatchers("/api/v1/search/**").permitAll()
            .antMatchers("/admin/**").hasRole("ADMIN")
               .anyRequest()
               .authenticated()
               .and()
               .httpBasic();
              
    }
 
}
我已经从:
http://localhost:8080/api/v1/
比如:

http://localhost:8080/api/v1/books
http://localhost:8080/api/v1/bookcategory
我已经使用
.antMatchers(“/api/v1/search/**”)进行了配置
,我对restendpoint的配置是:

@RequestMapping("/api/v1")
@RestController
@CrossOrigin(origins ="http://localhost:4200")
public class BasicAuthController {

    @GetMapping(path = "/basicauth")
    public AuthenticationBean basicauth() {
        System.out.println("hitted here");
        return new AuthenticationBean("You are authenticated");
    }
    
  
}
我允许csfr策略使用:

@Configuration
public class RepositoryConfig implements RepositoryRestConfigurer{

    @Autowired
    private EntityManager entityManager;
    
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(entityManager.getMetamodel().getEntities().stream()
                .map(Type::getJavaType).toArray(Class[]::new));
        
        
        //to handle cross origin
        config.getCorsRegistry().addMapping("/**").allowedOrigins("http://localhost:4200");
    }
}
BookRepository.java

public interface BookRepository extends JpaRepository<Book,Long> {

    @RestResource(path = "categoryid")
    Page<Book>  findByCategoryId(@Param("id") Long id,Pageable pageable);
    
    //to get book by searching
    @RestResource(path = "searchbykeyword")
    Page<Book>  findByNameContaining(@Param("xyz") String keyword,Pageable pageable);
}
//我没有粘贴所有的代码

所以,当我转到链接时,我得到了错误http://localhost:4200/books:


问题在于CORS,它是浏览器的一项安全功能。它确保只能访问来自同一域(和端口!)的资源。Angular development服务器和Tomcat在不同的端口上运行,这会导致请求被拒绝。您必须配置CORS。但是,您应该知道自己在做什么,因为您基本上禁用了安全功能。通常这不是一个问题。您可以通过将注释@CrossOrigin添加到控制器方法或使用Java配置来实现这一点。第二个原因,我相信你会很容易在谷歌上找到它:)

CORS(跨源资源共享)是浏览器的一项安全功能,可防止授权站点使用其他来源的资源

简而言之,如果您的站点位于x:y原点,并从a:y、x:b或a:b原点(不同的端口和/或域)请求资源,则会发生这种情况

简而言之,在这种情况下会发生什么

如果您从另一个来源发出get(或post…)请求,浏览器将首先向同一个端点发出
选项
请求,如果成功并具有所有允许的标题,它将发出get请求,如果不成功,它将抛出错误,指定拒绝和不发出原始请求的原因


所以我们现在有两种情况,要么只是在get请求中返回头,而不是选项一,要么它永远不会返回。我有一些项目使用Angular+SpringBoot进行安全性保护,我创建了一个特定的Bean来处理CORS,我从来没有遇到过问题。如果可以尝试,请在WebSecurity配置类中添加以下方法:

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200", "http://localhost:8080"));
    configuration.setAllowedMethods(Arrays.asList("GET", "PUT", "POST","OPTIONS", "DELETE"));
    configuration.setAllowedHeaders(Arrays.asList("authorization","content-type"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

我已将@crossorigin添加到每个rest端点,但它仍然不起作用。请您使用postman提供的
OPTIONS
方法尝试
localhost:8080/api/…
,看看是否返回了
Access Control Allow Origin
标题,它的值为
localhost:4200
*
,在这里阅读更多信息我在postman:curl-X选项中尝试了这一点-我和我无法得到任何响应您确定您从angular调用的端点是正确的吗?我一直在使用angular+springboot,我意识到当angular找不到目的地时,浏览器会发送CORS错误是的,当我从angular发送用户名和密码时,登录成功,当我刚刚点击浏览器上的其余端点时,我会看到数据,但是当这些api从angularif获取时,相同的目标链接被称为CSRF策略如果使用选项时没有得到响应,这意味着您没有配置api来捕获此方法,您必须添加它我应该导入哪个包,cors或.cors.reactive?import org.springframework.web.cors.cors配置;导入org.springframework.web.cors.cors配置源;导入org.springframework.web.cors.UrlBasedCorsConfigurationSource;使用此bean,您不需要在Controllers中使用@CrossOrigin注释。CORS策略仍然阻止了从源“”访问“”处的XMLHttpRequest的相同错误:请求的资源上不存在“Access Control Allow origin”头。我认为您调用的端点地址不正确。尝试删除Spring安全库并再次调用此端点。也许你会收到同样的错误。正如我之前所说的,我意识到有时候当浏览器找不到正确的目的地时,它会显示CORS错误
@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200", "http://localhost:8080"));
    configuration.setAllowedMethods(Arrays.asList("GET", "PUT", "POST","OPTIONS", "DELETE"));
    configuration.setAllowedHeaders(Arrays.asList("authorization","content-type"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}