From 020ce1e6f85dfec6c754a1870acfa25104457b91 Mon Sep 17 00:00:00 2001 From: Tibor Bossanyi Date: Wed, 29 Mar 2023 20:40:49 +0200 Subject: [PATCH] API 1.2.1 CORS --- .../api/controller/CustomerController.kt | 3 +- .../api/controller/PackageController.kt | 2 + .../AuthenticationControllerAspect.kt | 16 +++++++- .../api/security/JwtSecurityConfig.kt | 38 +++++++++++++------ .../resources/application-diet.properties | 2 + .../resources/application-dietprod.properties | 4 +- src/main/resources/application.properties | 4 +- .../com/aitrainer/api/test/AppPackageTest.kt | 6 +-- 8 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt b/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt index dda552b..1f7df54 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt @@ -42,7 +42,8 @@ class CustomerController ( private val customerRepository: CustomerRepository) { @Secured @GetMapping("/customers/{id}") - fun getCustomerById(@PathVariable(value = "id") customerId: Long, @RequestHeader headers: HttpHeaders): ResponseEntity { + @CrossOrigin(origins = ["http://localhost:48102"]) + fun getCustomerById(@PathVariable(value = "id") customerId: Long): ResponseEntity { val customer: Customer? = customerRepository.findById(customerId).orElse(null) return if (customer == null) ResponseEntity.notFound().build() else ResponseEntity.ok().body(customer) } diff --git a/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt b/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt index a862add..f19a5da 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import com.google.gson.GsonBuilder +import org.springframework.web.bind.annotation.CrossOrigin @RestController @@ -42,6 +43,7 @@ class PackageController(private val exerciseAbilityRepository: ExerciseAbilityRe ) { @GetMapping("/diet_package") + @CrossOrigin(origins = ["http://localhost:48102"]) fun getDietPackageData(): ResponseEntity { val gson = GsonBuilder() .excludeFieldsWithoutExposeAnnotation() diff --git a/src/main/kotlin/com/aitrainer/api/security/AuthenticationControllerAspect.kt b/src/main/kotlin/com/aitrainer/api/security/AuthenticationControllerAspect.kt index 9393a90..e22e3ce 100644 --- a/src/main/kotlin/com/aitrainer/api/security/AuthenticationControllerAspect.kt +++ b/src/main/kotlin/com/aitrainer/api/security/AuthenticationControllerAspect.kt @@ -28,10 +28,22 @@ class AuthenticationControllerAspect { Singleton.checkDBUpdate(configurationRepository, properties) } - @Before("execution(* com.aitrainer.api.security.JwtSecurityConfig.*(..))") + @Before("execution(* com.aitrainer.api.security.JwtSecurityConfig.filterChain(..))") fun securityControllerAspect(joinPoint: JoinPoint) { - println("JwtSecurity config join") + println("JwtSecurity FilterChain config join") Singleton.checkDBUpdate(configurationRepository, properties) } + @Before("execution(* com.aitrainer.api.security.JwtSecurityConfig.corsMappingConfigurer(..))") + fun corsControllerAspect(joinPoint: JoinPoint) { + println("JwtSecurity CorsMapper config join") + Singleton.checkDBUpdate(configurationRepository, properties) + } + + /* @Before("execution(* com.aitrainer.api.security.JwtRequestFilter.doFilterInternal(..))") + fun requestFilterAspect(joinPoint: JoinPoint) { + println("JwtRequestFilter join") + Singleton.checkDBUpdate(configurationRepository, properties) + }*/ + } diff --git a/src/main/kotlin/com/aitrainer/api/security/JwtSecurityConfig.kt b/src/main/kotlin/com/aitrainer/api/security/JwtSecurityConfig.kt index 754c728..e9f05b2 100644 --- a/src/main/kotlin/com/aitrainer/api/security/JwtSecurityConfig.kt +++ b/src/main/kotlin/com/aitrainer/api/security/JwtSecurityConfig.kt @@ -12,10 +12,13 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.http.SessionCreationPolicy import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - +import org.springframework.web.servlet.config.annotation.CorsRegistry +import org.springframework.web.servlet.config.annotation.EnableWebMvc +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer @Configuration @EnableWebSecurity +@EnableWebMvc class JwtSecurityConfig { @Autowired private val jwtAuthenticationEntryPoint: JwtAuthenticationEntryPoint? = null @@ -33,24 +36,37 @@ class JwtSecurityConfig { val authenticationManagerBuilder = http.getSharedObject( AuthenticationManagerBuilder::class.java ) - authenticationManagerBuilder.userDetailsService(jwtUserDetailsService).passwordEncoder(serviceBeans!!.passwordEncoder()) + authenticationManagerBuilder.userDetailsService(jwtUserDetailsService) + .passwordEncoder(serviceBeans!!.passwordEncoder()) return authenticationManagerBuilder.build() } @Bean @Throws(Exception::class) - fun filterChain(httpSecurity: HttpSecurity):SecurityFilterChain { + fun filterChain(httpSecurity: HttpSecurity): SecurityFilterChain { - httpSecurity. - csrf().disable(). - authorizeHttpRequests().requestMatchers("/api/authenticate").permitAll(). - anyRequest().authenticated().and(). - exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and(). - addFilterAfter(jwtRequestFilter, UsernamePasswordAuthenticationFilter::class.java). + httpSecurity.cors().and().csrf().disable().authorizeHttpRequests().requestMatchers("/api/authenticate").permitAll() + .anyRequest().authenticated().and().exceptionHandling() + .authenticationEntryPoint(jwtAuthenticationEntryPoint).and() + .addFilterAfter(jwtRequestFilter, UsernamePasswordAuthenticationFilter::class.java). // make sure we use stateless session; session won't be used to // store user's state. - sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) return httpSecurity.build(); } -} + + @Bean + fun corsMappingConfigurer(): WebMvcConfigurer? { + return object : WebMvcConfigurer { + override fun addCorsMappings(registry: CorsRegistry) { + registry.addMapping("/**") + .allowedOriginPatterns("https://*.diet4you.eu", "https://*.diet4you.hu", "https://*.workouttest.org", "http://localhost:[*]") + //.allowedOrigins("*") + .allowedMethods("POST", "GET", "OPTIONS", "HEAD") + .maxAge(3600) + .allowedHeaders("*") + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/application-diet.properties b/src/main/resources/application-diet.properties index b28635d..3a03dde 100644 --- a/src/main/resources/application-diet.properties +++ b/src/main/resources/application-diet.properties @@ -23,3 +23,5 @@ jwt.secret=aitrainer openai.key=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 firebase.key=AIzaSyBLn7Bz73Z1hB-OhqphBDsskOyGmpI7J8E spring.mail.properties.mail.mime.charset=UTF-8 + +spring.mvc.cors.allowed-origins=* \ No newline at end of file diff --git a/src/main/resources/application-dietprod.properties b/src/main/resources/application-dietprod.properties index 477278a..a055290 100644 --- a/src/main/resources/application-dietprod.properties +++ b/src/main/resources/application-dietprod.properties @@ -20,4 +20,6 @@ jwt.secret=aitrainer firebase.key=AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4 openai.key=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 -spring.mail.properties.mail.mime.charset=UTF-8 \ No newline at end of file +spring.mail.properties.mail.mime.charset=UTF-8 + +spring.mvc.cors.allowed-origins=* \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cae4e88..ae65df9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -23,4 +23,6 @@ jwt.secret=aitrainer openai.key=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 spring.mail.properties.mail.mime.charset=UTF-8 -firebase.key=AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4 \ No newline at end of file +firebase.key=AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4 + +spring.mvc.cors.allowed-origins=* \ No newline at end of file diff --git a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt index dbca57d..af29377 100644 --- a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt @@ -394,9 +394,9 @@ class AppPackageTest { val appTextJson: String = record[1] val type = object : TypeToken?>() {}.type val texts: List = gson.fromJson(appTextJson, type) - assertEquals(texts.size, 2) - assertEquals(texts[0].translations[0].translation, "Done!") - assertEquals(texts[0].translations[1].translation, "Kész!") + assertEquals(texts.size, 15) + assertEquals(texts[13].translations[0].translation, "Done!") + assertEquals(texts[13].translations[1].translation, "Kész!") } else if (record[0] == TrainingProgram::class.simpleName) { val trainingProgramJson: String = record[1] val type = object : TypeToken?>() {}.type