security 추가 새로운 삽질 거리

This commit is contained in:
lunaticbum 2024-10-05 19:15:51 +09:00
parent dfa6b28a66
commit b27b9ff60f
8 changed files with 175 additions and 14 deletions

View File

@ -41,7 +41,7 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-security")
compileOnly("org.projectlombok:lombok")
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
annotationProcessor("org.projectlombok:lombok")

View File

@ -0,0 +1,103 @@
package kr.lunaticbum.back.lun.configs
import com.fasterxml.jackson.databind.ObjectMapper
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import kr.lunaticbum.back.lun.model.Role
import kr.lunaticbum.back.lun.utils.LogService
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory.disable
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.security.servlet.PathRequest
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.security.access.AccessDeniedException
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.core.AuthenticationException
import org.springframework.security.web.AuthenticationEntryPoint
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.access.AccessDeniedHandler
import org.springframework.web.ErrorResponse
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Autowired
lateinit var logService: LogService
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http.csrf {
it.ignoringRequestMatchers("/user/joinUser.ajax").disable()
}
http.cors { it.disable() }
http.headers {
it.frameOptions { frameOptionsConfig ->
frameOptionsConfig.disable()
}
}
http.authorizeHttpRequests {
logService.log(it.toString())
it.requestMatchers(HttpMethod.POST,"/user/**").permitAll()
// it.requestMatchers("/", "/user/**").permitAll()
// .requestMatchers(".ajax").permitAll()
// it.requestMatchers("/", "/user/joinUser.api").permitAll()
// it.requestMatchers("user/joinUser.api").permitAll()
it.anyRequest().permitAll()
// .requestMatchers("/", "/login/**").permitAll()
// .requestMatchers("/posts/**", "/api/v1/posts/**").hasRole(Role.USER.name)
// .requestMatchers("/admins/**", "/api/v1/admins/**").hasRole(Role.ADMIN.name)
// .anyRequest().authenticated()
}
http.sessionManagement {
it.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
}
.exceptionHandling { it ->
it.authenticationEntryPoint(unauthorizedEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
}
// .formLogin { formLogin ->
// formLogin
// .loginPage("/user/join")
////// .usernameParameter("username")
////// .passwordParameter("password")
// .loginProcessingUrl("/user/joinUser.api")
// .defaultSuccessUrl("/", true)
// }
return http.build()
}
private val unauthorizedEntryPoint =
AuthenticationEntryPoint { request: HttpServletRequest?, response: HttpServletResponse, authException: AuthenticationException? ->
val fail: ErrorResponse = ErrorResponse.create( Throwable("아직 못들어와"),
HttpStatus.UNAUTHORIZED, "Spring security unauthorized..."
)
response.status = HttpStatus.UNAUTHORIZED.value()
val json = ObjectMapper().writeValueAsString(fail)
response.contentType = MediaType.APPLICATION_JSON_VALUE
val writer = response.writer
writer.write(json)
writer.flush()
}
private val accessDeniedHandler =
AccessDeniedHandler { request: HttpServletRequest?, response: HttpServletResponse, accessDeniedException: AccessDeniedException? ->
val fail: ErrorResponse = ErrorResponse.create( Throwable("아직 못들어와"),
HttpStatus.FORBIDDEN, "Spring security forbidden..."
)
response.status = HttpStatus.FORBIDDEN.value()
val json = ObjectMapper().writeValueAsString(fail)
response.contentType = MediaType.APPLICATION_JSON_VALUE
val writer = response.writer
writer.write(json)
writer.flush()
}
}

View File

@ -0,0 +1,5 @@
package kr.lunaticbum.back.lun.controllers
class Owner {
}

View File

@ -44,7 +44,7 @@ class UserController {
@ResponseBody
@PostMapping("joinUser.api")
@PostMapping("/joinUser.ajax")
fun joinUser(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<ResponceResult> {
logService.log("${httpServletRequest.requestURI}")
logService.log(jsonString)
@ -75,7 +75,10 @@ class UserController {
}
logService.log(fullData.joinToString(""))
var user = Gson().fromJson(fullData.joinToString(""), User::class.java)
var u = userManager.save(user).block()
var u : User? = null
if (user.checkValid()) {
u = userManager.save(user).block()
}
val responce = ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(ResponceResult().apply {
resultCode = if (u != null) 0 else 8245
resultMsg = if (u != null) "OK" else "User Insert Fail"

View File

@ -1,19 +1,23 @@
package kr.lunaticbum.back.lun.model
import jdk.jfr.Description
import kotlinx.coroutines.reactive.awaitFirst
import kotlinx.coroutines.reactive.awaitFirstOrElse
import kr.lunaticbum.back.lun.utils.LogService
import lombok.AllArgsConstructor
import lombok.Data
import lombok.NoArgsConstructor
import lombok.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Primary
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.data.mongodb.repository.Query
import org.springframework.data.mongodb.repository.ReactiveMongoRepository
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.stereotype.Repository
import org.springframework.stereotype.Service
import reactor.core.publisher.Mono
import java.time.Duration
@Data
@NoArgsConstructor
@ -32,8 +36,39 @@ class User {
var user_name: String? = null
var isAccept : String? = null
var isAdmin : String? = null
fun checkValid() : Boolean {
if (
((user_id?.length ?: 0) > 5) &&
((user_pw?.length ?: 0) > 9) &&
((user_email?.length ?: 0) > 8) &&
user_email?.contains("@") == true &&
user_email?.contains(".") == true &&
(user_email?.split("@")?.get(0)?.length ?: 0) > 1 &&
(user_email?.split("@")?.get(1)?.length ?: 0) > 1 &&
(user_email?.split(".")?.get(1)?.length ?: 0) > 1
) {
if (user_id.equals("lun_admin") || user_id.equals("lunaticbum")){
isAdmin = "Y"
} else {
isAccept = "N"
isAdmin = "N"
}
return true
}
return false
}
}
@Getter
@RequiredArgsConstructor
enum class Role(key : String, description: String) {
USER("ROLE_USER", "일반사용자"),
ADMIN("ROLE_ADMIN", "일반관리자");
private val key: String? = null
private val title: String? = null
}
@Repository
interface UserRepository : ReactiveMongoRepository<User, String> {
@ -48,7 +83,7 @@ interface UserService {
}
@Service
class UserManager : UserService {
class UserManager : UserService , UserDetailsService {
@Autowired
private lateinit var logService: LogService
@ -70,4 +105,10 @@ class UserManager : UserService {
// println("saved user comp")
// })
}
override fun loadUserByUsername(username: String?): UserDetails {
var user = findById(username!!)?.blockOptional(Duration.ofMillis(5000L))?.get() ?: User()
logService.log("username ${username}")
return org.springframework.security.core.userdetails.User.builder().username(user.user_id ?: "").password(user.user_pw).roles(if ("Y".equals(user.isAdmin)) Role.ADMIN.name else {Role.USER.name}).build()
}
}

View File

@ -0,0 +1,8 @@
package kr.lunaticbum.back.lun.service
import kr.lunaticbum.back.lun.model.User
import kr.lunaticbum.back.lun.model.UserRepository
import lombok.RequiredArgsConstructor
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.stereotype.Service

View File

@ -9,10 +9,10 @@ spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
#spring.data.mongodb.port=27017
#spring.data.mongodb.database=lun_db
#SSL
server.ssl.key-store=classpath:prv.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=VioPup*383
server.http2.enabled=true
#server.ssl.key-store=classpath:prv.p12
#server.ssl.key-store-type=PKCS12
#server.ssl.key-store-password=VioPup*383
#server.http2.enabled=true
#spring.main.web-application-type=SERVLET
#logging.level.org.springframework.boot.autoconfigure=ERROR
#spring.mvc.view.prefix=/templates
@ -28,7 +28,7 @@ spring.thymeleaf.suffix=.html
telegram.bot.key=1
telegram.my.id=2
telegram.target.id=3
weather.api.key=3
weather.api.key=3
spring.data.mongodb.option.min-connection-per-host=0
spring.data.mongodb.option.max-connection-per-host=100
spring.data.mongodb.option.threads-allowed-to-block-for-connection-multiplier=5

View File

@ -94,12 +94,13 @@
// document.getElementById("name").innerText = result.name;
// document.getElementById("age").innerText = result.age;
} else {
alert(httpRequest.response);
alert('Request Error!');
}
}
};
/* Get 방식으로 name 파라미터와 함께 요청 */
httpRequest.open('POST', 'joinUser.api', true);
httpRequest.open('POST', 'joinUser.ajax', true);
httpRequest.setRequestHeader("Content-Type", "text/plain");
let data = {