当前位置: 首页 > 知识库问答 >
问题:

没有访问控制允许原点标头存在(CROS)-Spring Boot(Spring Security)微服务Vue.js

燕翼
2023-03-14

为了避免CORS错误,我通常会在类中添加@CrossOrigin注释,它可以工作。这一切都很好,一直工作得很好,直到我添加了安全部分,能够登录用户。

1.API网关建立在spring cloud Gateway之上,我添加了AuthFilter作为截取器来创建和检查JWT:/AuthFilter。java

@Component
public class AuthFilter extends AbstractGatewayFilterFactory<AuthFilter.Config> {
    private final WebClient.Builder webClientBuilder;

    @Autowired
    public AuthFilter(WebClient.Builder webClientBuilder) {
        super(Config.class);
        this.webClientBuilder = webClientBuilder;
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            if(!exchange.getRequest().getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
                throw new RuntimeException("Missing auth information");
            }

            String authHeader = exchange.getRequest().getHeaders().get(org.springframework.http.HttpHeaders.AUTHORIZATION).get(0);
            String[] parts = authHeader.split(" ");

            if(parts.length != 2 || !"Bearer".equals(parts[0])) {
                throw new RuntimeException("Incorrect auth structure");
            }

            return webClientBuilder.build()
                    .post()
                    .uri("http://manager-service/api/v1/auth/validateToken?token=" + parts[1])
                    .retrieve()
                    .bodyToMono(EmployeeDTO.class) //EmployeeDTO.class is custom DTO that represents User
                    .map(user -> {
                        exchange.getRequest()
                                .mutate()
                                .header("x-auth-user-id", user.getId());
                        return exchange;
                    }).flatMap(chain::filter);

        };
    }

    public static class Config {
        //live it empty because we dont need any particular configuration
    }
}

2.我已经添加AuthFilter作为过滤器到application.properties中的每个服务:
api网关/src/资源/application.properties

##Workshop service routes
spring.cloud.gateway.routes[0].id=workshop-service
spring.cloud.gateway.routes[0].uri=lb://workshop-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/v1/workshop/**
spring.cloud.gateway.routes[0].filters[0]=AuthFilter

##Manage service routes
spring.cloud.gateway.routes[1].id=manager-service
spring.cloud.gateway.routes[1].uri=lb://manager-service
spring.cloud.gateway.routes[1].predicates[0]=Path=/api/v1/manage/**
spring.cloud.gateway.routes[1].filters[0]=AuthFilter

##Manage service for singIn. Here we dont need to add AuthFilter, cause sign in page should be available for all
spring.cloud.gateway.routes[2].id=manager-service-sign-in
spring.cloud.gateway.routes[2].uri=lb://manager-service
spring.cloud.gateway.routes[2].predicates[0]=Path=/api/v1/auth/signIn

...

3.Manager服务微服务用于控制系统的基本实体,如用户、角色、用户所在的组织等,因此我在这里添加了SecurityConfig和WebConfig,因为该微服务将负责生成JWT:br>Manager服务/src/main/java//安全配置。java

@EnableWebSecurity
public class SecurityConfig  {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf().disable()
                .authorizeRequests().anyRequest().permitAll();
        return httpSecurity.build();
    }
   }

Manager-service/src/main/java/... /WebConfig.java

@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    private static final Long MAX_AGE=3600L;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedHeaders(
                        HttpHeaders.AUTHORIZATION,
                        HttpHeaders.CONTENT_TYPE,
                        HttpHeaders.ACCEPT)
                .allowedMethods(
                        HttpMethod.GET.name(),
                        HttpMethod.POST.name(),
                        HttpMethod.PUT.name(),
                        HttpMethod.DELETE.name())
                .maxAge(MAX_AGE)
                .allowedOrigins("http://localhost:8100")
                .allowCredentials(false);
    }
}

4.在控制器中,表示身份验证,我还在类中添加了@CrossOrigin注释:
Manager-service/src/main/java/... /AuthC

@RestController
@RequestMapping("api/v1/auth")
@CrossOrigin(origins = "http://localhost:8100")
@Slf4j
public class AuthController {
    private final AuthService authService;

    @Autowired
    public AuthController(AuthService authService) {
        this.authService = authService;
    }

    @PostMapping("/signIn")
    public ResponseEntity<EmployeeDTO> signIn(@RequestBody CredentialsDTO credentialsDTO) {
        log.info("Trying to login {}", credentialsDTO.getLogin());

        return ResponseEntity.ok(EmployeeMapper.convertToDTO(authService.signIn(credentialsDTO)));
    }

    @PostMapping("/validateToken")
    public ResponseEntity<EmployeeDTO> validateToken(@RequestParam String token) {
        log.info("Trying to validate token {}", token);
        Employee validatedTokenUser = authService.validateToken(token);
        return ResponseEntity.ok(EmployeeMapper.convertToDTO(validatedTokenUser));
    }
}

5.对于前端,我使用Vue.js.对于请求,我使用axios。这里是post-登录请求:

axios.post('http://localhost:8080/api/v1/auth/signIn', this.credentials).then(response => {
              console.log('response = ', response)
              console.log('token from response', response.data.token)
              this.$store.commit('saveToken', response.data.token)
            }).catch(error => {
          console.log('Error is below')
          console.log(error)
        })

我会感激任何我能做错什么的想法。谢谢!


共有1个答案

唐威
2023-03-14

我也遇到过类似的问题

@Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Collections.singletonList("http://localhost:8100")); // Provide list of origins if you want multiple origins
        config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
        config.setAllowCredentials(true);
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

您可以注释掉所有其他详细信息,例如,@CrossOrigin(origins=”http://localhost:8100“)、WebConfig.java、SecurityConfig.java一旦我们定义了上述bean,这些东西就不再是必需的了。

您的代码可能无法运行,因为您定义了bean、安全配置以及webconfig,这些配置在处理您的请求时可能会发生冲突。

 类似资料:
  • 我有一个amp list元素,它的src是一个搜索。包含产品信息的php文件。 在验证时,我认为tld没有AMP访问控制允许源代码源标题,尽管我已经设置了一个。以下是php文件: 和html: 我做错了什么?我已经阅读了这里的其他问题,并试图修改我的代码,但没有成功。

  • 我正在开发一个带有jhipster V4.5.6的Spring启动应用程序。但无法配置 CORS。 下面是我的application-dev.yml文件: WebConfigurer.java如下: 和安全配置。java文件如下所示: 现在,我可以使用 GET 请求。但是当我使用POST时,如下所示: 我得到以下错误: XMLHttpRequest 无法加载 http://localhost:80

  • 我得到访问控制允许来源错误。 CORS策略阻止从来源“https://localhost:44322”访问“https://localhost:44301/api/xxxx/getallxxxx”处的XMLHttpRequest:对飞行前请求的响应未通过访问控制检查:请求的资源上没有“access-control-allog-origin”标头。 下面是我的头,我已经传递给api调用。 我是否丢失

  • 我需要从后端下载图像 Asp Core 2.2 并在 Angular 中显示它。 i 为以角度显示图像创建一个组件: 在 Html 代码中 : 在Ts文件中: 在使用中: 现在,当我需要显示图像时,它会在控制台中向我显示此错误: 在“中”访问XMLHttpRequesthttps://localhost:44372/Uplaod/NewsPictureFolder/NewsMainPicture/

  • 我陷入了API网关的问题,我已经浏览了AWS论坛上的所有其他SO答案,并浏览了他们的文档,但仍然没有乐趣。 我正在尝试使用AWS API gateway设置一个API,该API调用一个Lambda函数,该函数读取/写入DynamoDB中的一个表。 DynamoDB的Lambda函数正在工作。我在AWS中创建了一个API,并为它创建了GET和OPTIONS方法。我了解到AWS并不强制只使用GET/P