package com.android.trisolarisserver.security import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.http.SessionCreationPolicy import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter import org.springframework.security.web.authentication.HttpStatusEntryPoint import org.springframework.http.HttpStatus import com.fasterxml.jackson.databind.ObjectMapper import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse @Configuration(proxyBeanMethods = false) @EnableMethodSecurity class SecurityConfig( private val firebaseAuthFilter: FirebaseAuthFilter, private val objectMapper: ObjectMapper ) { @Bean fun filterChain(http: HttpSecurity): SecurityFilterChain { http .csrf { it.disable() } .sessionManagement { it.sessionCreationPolicy(SessionCreationPolicy.STATELESS) } .authorizeHttpRequests { it.requestMatchers("/", "/health", "/auth/**").permitAll() it.requestMatchers("/properties/*/rooms/*/images/*/file").permitAll() it.requestMatchers("/properties/*/rooms/*/images").permitAll() it.requestMatchers("/properties/*/room-types").permitAll() it.requestMatchers(org.springframework.http.HttpMethod.GET, "/image-tags").permitAll() it.anyRequest().authenticated() } .exceptionHandling { it.authenticationEntryPoint { request, response, _ -> writeError(response, request, HttpStatus.UNAUTHORIZED, "Unauthorized") } it.accessDeniedHandler { request, response, _ -> writeError(response, request, HttpStatus.FORBIDDEN, "Forbidden") } } .httpBasic { it.disable() } .formLogin { it.disable() } .addFilterBefore(firebaseAuthFilter, UsernamePasswordAuthenticationFilter::class.java) return http.build() } private fun writeError( response: HttpServletResponse, request: HttpServletRequest, status: HttpStatus, message: String ) { if (response.isCommitted) return response.status = status.value() response.contentType = "application/json" val body = mapOf( "status" to status.value(), "error" to status.reasonPhrase, "message" to message, "path" to request.requestURI ) response.writer.use { it.write(objectMapper.writeValueAsString(body)) } } }