security 추가 새로운 삽질 거리
This commit is contained in:
parent
dfa6b28a66
commit
b27b9ff60f
@ -41,7 +41,7 @@ dependencies {
|
|||||||
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
|
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||||
compileOnly("org.projectlombok:lombok")
|
compileOnly("org.projectlombok:lombok")
|
||||||
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
|
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
|
||||||
annotationProcessor("org.projectlombok:lombok")
|
annotationProcessor("org.projectlombok:lombok")
|
||||||
|
|||||||
103
src/main/kotlin/kr/lunaticbum/back/lun/configs/SecurityConfig.kt
Normal file
103
src/main/kotlin/kr/lunaticbum/back/lun/configs/SecurityConfig.kt
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package kr.lunaticbum.back.lun.controllers
|
||||||
|
|
||||||
|
class Owner {
|
||||||
|
|
||||||
|
}
|
||||||
@ -44,7 +44,7 @@ class UserController {
|
|||||||
|
|
||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PostMapping("joinUser.api")
|
@PostMapping("/joinUser.ajax")
|
||||||
fun joinUser(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<ResponceResult> {
|
fun joinUser(httpServletRequest: HttpServletRequest, @RequestBody jsonString: String) : ResponseEntity<ResponceResult> {
|
||||||
logService.log("${httpServletRequest.requestURI}")
|
logService.log("${httpServletRequest.requestURI}")
|
||||||
logService.log(jsonString)
|
logService.log(jsonString)
|
||||||
@ -75,7 +75,10 @@ class UserController {
|
|||||||
}
|
}
|
||||||
logService.log(fullData.joinToString(""))
|
logService.log(fullData.joinToString(""))
|
||||||
var user = Gson().fromJson(fullData.joinToString(""), User::class.java)
|
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 {
|
val responce = ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(ResponceResult().apply {
|
||||||
resultCode = if (u != null) 0 else 8245
|
resultCode = if (u != null) 0 else 8245
|
||||||
resultMsg = if (u != null) "OK" else "User Insert Fail"
|
resultMsg = if (u != null) "OK" else "User Insert Fail"
|
||||||
|
|||||||
@ -1,19 +1,23 @@
|
|||||||
package kr.lunaticbum.back.lun.model
|
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 kr.lunaticbum.back.lun.utils.LogService
|
||||||
import lombok.AllArgsConstructor
|
import lombok.*
|
||||||
import lombok.Data
|
|
||||||
import lombok.NoArgsConstructor
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.context.annotation.Primary
|
|
||||||
import org.springframework.data.annotation.CreatedDate
|
import org.springframework.data.annotation.CreatedDate
|
||||||
import org.springframework.data.annotation.Id
|
import org.springframework.data.annotation.Id
|
||||||
import org.springframework.data.mongodb.core.mapping.Document
|
import org.springframework.data.mongodb.core.mapping.Document
|
||||||
import org.springframework.data.mongodb.repository.Query
|
import org.springframework.data.mongodb.repository.Query
|
||||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository
|
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.Repository
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
|
import java.time.Duration
|
||||||
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@ -32,8 +36,39 @@ class User {
|
|||||||
var user_name: String? = null
|
var user_name: String? = null
|
||||||
var isAccept : String? = null
|
var isAccept : String? = null
|
||||||
var isAdmin : 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
|
@Repository
|
||||||
interface UserRepository : ReactiveMongoRepository<User, String> {
|
interface UserRepository : ReactiveMongoRepository<User, String> {
|
||||||
@ -48,7 +83,7 @@ interface UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class UserManager : UserService {
|
class UserManager : UserService , UserDetailsService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private lateinit var logService: LogService
|
private lateinit var logService: LogService
|
||||||
|
|
||||||
@ -70,4 +105,10 @@ class UserManager : UserService {
|
|||||||
// println("saved user comp")
|
// 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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
@ -9,10 +9,10 @@ spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
|
|||||||
#spring.data.mongodb.port=27017
|
#spring.data.mongodb.port=27017
|
||||||
#spring.data.mongodb.database=lun_db
|
#spring.data.mongodb.database=lun_db
|
||||||
#SSL
|
#SSL
|
||||||
server.ssl.key-store=classpath:prv.p12
|
#server.ssl.key-store=classpath:prv.p12
|
||||||
server.ssl.key-store-type=PKCS12
|
#server.ssl.key-store-type=PKCS12
|
||||||
server.ssl.key-store-password=VioPup*383
|
#server.ssl.key-store-password=VioPup*383
|
||||||
server.http2.enabled=true
|
#server.http2.enabled=true
|
||||||
#spring.main.web-application-type=SERVLET
|
#spring.main.web-application-type=SERVLET
|
||||||
#logging.level.org.springframework.boot.autoconfigure=ERROR
|
#logging.level.org.springframework.boot.autoconfigure=ERROR
|
||||||
#spring.mvc.view.prefix=/templates
|
#spring.mvc.view.prefix=/templates
|
||||||
|
|||||||
@ -94,12 +94,13 @@
|
|||||||
// document.getElementById("name").innerText = result.name;
|
// document.getElementById("name").innerText = result.name;
|
||||||
// document.getElementById("age").innerText = result.age;
|
// document.getElementById("age").innerText = result.age;
|
||||||
} else {
|
} else {
|
||||||
|
alert(httpRequest.response);
|
||||||
alert('Request Error!');
|
alert('Request Error!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/* Get 방식으로 name 파라미터와 함께 요청 */
|
/* Get 방식으로 name 파라미터와 함께 요청 */
|
||||||
httpRequest.open('POST', 'joinUser.api', true);
|
httpRequest.open('POST', 'joinUser.ajax', true);
|
||||||
httpRequest.setRequestHeader("Content-Type", "text/plain");
|
httpRequest.setRequestHeader("Content-Type", "text/plain");
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user