[#41] modify: 전체적인 리팩토링
- Security 관련 JWT filter, configurer 공통 코드 common 모듈화 - flyway 불필요한 설정 제거
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package io.beaniejoy.dongnecafe.common.config
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.utils.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.config.JwtAuthenticationConfigurer
|
||||
import io.beaniejoy.dongnecafe.security.handler.CustomAccessDeniedHandler
|
||||
import io.beaniejoy.dongnecafe.security.handler.CustomAuthenticationEntryPoint
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.beaniejoy.dongnecafe.controller
|
||||
|
||||
import io.beaniejoy.dongnecafe.common.response.ApplicationResponse
|
||||
import io.beaniejoy.dongnecafe.security.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.utils.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.domain.member.model.request.SignInRequest
|
||||
import io.beaniejoy.dongnecafe.model.TokenResponse
|
||||
import io.beaniejoy.dongnecafe.service.AuthService
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package io.beaniejoy.dongnecafe.security.filter
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.BEARER
|
||||
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.WHITESPACE
|
||||
import mu.KotlinLogging
|
||||
import org.springframework.http.HttpHeaders
|
||||
import org.springframework.security.core.context.SecurityContextHolder
|
||||
import org.springframework.web.filter.GenericFilterBean
|
||||
import javax.servlet.FilterChain
|
||||
import javax.servlet.ServletRequest
|
||||
import javax.servlet.ServletResponse
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
|
||||
class JwtAuthenticationFilter(
|
||||
private val jwtTokenUtils: JwtTokenUtils
|
||||
) : GenericFilterBean() {
|
||||
private val log = KotlinLogging.logger {}
|
||||
|
||||
/**
|
||||
* JWT access token 인증 처리
|
||||
*/
|
||||
override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
|
||||
val httpRequest = request as HttpServletRequest
|
||||
log.info { "[JwtAuthenticationFilter][${request.dispatcherType}] uri: ${request.requestURI}" }
|
||||
|
||||
getAccessToken(httpRequest)?.let {
|
||||
jwtTokenUtils.getAuthentication(it)
|
||||
}?.also {
|
||||
SecurityContextHolder.getContext().authentication = it
|
||||
log.info { "Valid Access Token [${it.name}]" }
|
||||
}
|
||||
|
||||
chain.doFilter(request, response)
|
||||
}
|
||||
|
||||
private fun getAccessToken(request: HttpServletRequest): String? {
|
||||
val bearer = request.getHeader(HttpHeaders.AUTHORIZATION)
|
||||
?: return null
|
||||
|
||||
val splitBearer = bearer.split(WHITESPACE)
|
||||
if (splitBearer.first() != BEARER) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (splitBearer.size != 2 || splitBearer.last().isBlank()) {
|
||||
return null
|
||||
}
|
||||
|
||||
return splitBearer.last()
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
server:
|
||||
port: 9090
|
||||
|
||||
spring:
|
||||
profiles:
|
||||
active: local
|
||||
@@ -5,22 +8,17 @@ spring:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: none # use flyway migration
|
||||
ddl-auto: none
|
||||
properties:
|
||||
hibernate:
|
||||
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
|
||||
dialect: org.hibernate.dialect.MySQL8Dialect
|
||||
format_sql: true
|
||||
show-sql: false
|
||||
open-in-view:
|
||||
flyway:
|
||||
enabled: false
|
||||
devtools:
|
||||
livereload:
|
||||
enabled: false # no use devtools' LiveReload Server
|
||||
|
||||
server:
|
||||
port: 9090
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.hibernate.SQL: debug # logger 통해 로깅
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.beaniejoy.dongnecafe.common.config
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.getAuthPrincipal
|
||||
import io.beaniejoy.dongnecafe.security.utils.getAuthPrincipal
|
||||
import mu.KLogging
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.beaniejoy.dongnecafe.security.config
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.filter.JwtAuthenticationFilter
|
||||
import io.beaniejoy.dongnecafe.security.utils.JwtTokenUtils
|
||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
import org.springframework.security.web.DefaultSecurityFilterChain
|
||||
@@ -6,4 +6,6 @@ object SecurityConstant {
|
||||
|
||||
const val ANONYMOUS_USER = "anonymousUser"
|
||||
const val ROLE_ANONYMOUS = "ROLE_ANONYMOUS"
|
||||
|
||||
const val JWT_AUTHORITIES_KEY = "authorities"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.beaniejoy.dongnecafe.security.filter
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.utils.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.BEARER
|
||||
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.WHITESPACE
|
||||
import mu.KotlinLogging
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.beaniejoy.dongnecafe.security
|
||||
package io.beaniejoy.dongnecafe.security.utils
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.SecurityUser
|
||||
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.JWT_AUTHORITIES_KEY
|
||||
import io.jsonwebtoken.Claims
|
||||
import io.jsonwebtoken.ExpiredJwtException
|
||||
import io.jsonwebtoken.Jwts
|
||||
@@ -24,9 +26,7 @@ class JwtTokenUtils(
|
||||
private val key: Key = Keys.hmacShaKeyFor(secretKey.toByteArray())
|
||||
private val validityTimeMilliSec: Long = validityTimeSec * 1000
|
||||
|
||||
companion object : KLogging() {
|
||||
const val AUTHORITIES_KEY = "authorities"
|
||||
}
|
||||
companion object : KLogging()
|
||||
|
||||
fun createToken(authentication: Authentication): String {
|
||||
val authenticatedMember = (authentication.principal as SecurityUser).member
|
||||
@@ -37,7 +37,7 @@ class JwtTokenUtils(
|
||||
|
||||
return Jwts.builder()
|
||||
.setSubject(authenticatedMember.email)
|
||||
.claim(AUTHORITIES_KEY, authorities)
|
||||
.claim(JWT_AUTHORITIES_KEY, authorities)
|
||||
.signWith(key, SignatureAlgorithm.HS256)
|
||||
.setExpiration(expirationDate)
|
||||
.compact()
|
||||
@@ -47,7 +47,7 @@ class JwtTokenUtils(
|
||||
val claims = getValidTokenBody(accessToken)
|
||||
?: return null
|
||||
|
||||
val authorities = claims[AUTHORITIES_KEY].toString().split(",")
|
||||
val authorities = claims[JWT_AUTHORITIES_KEY].toString().split(",")
|
||||
.map { SimpleGrantedAuthority(it) }
|
||||
|
||||
return UsernamePasswordAuthenticationToken(claims.subject, accessToken, authorities)
|
||||
@@ -62,10 +62,10 @@ class JwtTokenUtils(
|
||||
.parseClaimsJws(accessToken)
|
||||
.body
|
||||
} catch (e: ExpiredJwtException) {
|
||||
logger.error { "JWT access token expired. > Error: ${e.message}" }
|
||||
logger.info { "JWT access token expired. > Error: ${e.message}" }
|
||||
null
|
||||
} catch (e: Exception) {
|
||||
logger.error { "JWT access token invalid. > Error: ${e.message}" }
|
||||
logger.info { "JWT access token invalid. > Error: ${e.message}" }
|
||||
null
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.beaniejoy.dongnecafe.security
|
||||
package io.beaniejoy.dongnecafe.security.utils
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.ANONYMOUS_USER
|
||||
import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.ROLE_ANONYMOUS
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.beaniejoy.dongnecafe.common.config
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.JwtAuthenticationConfigurer
|
||||
import io.beaniejoy.dongnecafe.security.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.config.JwtAuthenticationConfigurer
|
||||
import io.beaniejoy.dongnecafe.security.utils.JwtTokenUtils
|
||||
import io.beaniejoy.dongnecafe.security.handler.CustomAccessDeniedHandler
|
||||
import io.beaniejoy.dongnecafe.security.handler.CustomAuthenticationEntryPoint
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.beaniejoy.dongnecafe.security
|
||||
|
||||
import io.beaniejoy.dongnecafe.security.filter.JwtAuthenticationFilter
|
||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||
import org.springframework.security.web.DefaultSecurityFilterChain
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
|
||||
|
||||
class JwtAuthenticationConfigurer :
|
||||
SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>() {
|
||||
private lateinit var jwtTokenUtils: JwtTokenUtils
|
||||
|
||||
override fun configure(http: HttpSecurity) {
|
||||
http
|
||||
.addFilterBefore(
|
||||
JwtAuthenticationFilter(this.jwtTokenUtils),
|
||||
UsernamePasswordAuthenticationFilter::class.java
|
||||
)
|
||||
}
|
||||
|
||||
fun jwtTokenUtils(jwtTokenUtils: JwtTokenUtils): JwtAuthenticationConfigurer {
|
||||
this.jwtTokenUtils = jwtTokenUtils
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,10 @@ spring:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: none # flyway migration 사용
|
||||
ddl-auto: none
|
||||
properties:
|
||||
hibernate:
|
||||
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
|
||||
dialect: org.hibernate.dialect.MySQL8Dialect
|
||||
format_sql: true
|
||||
show-sql: false
|
||||
devtools:
|
||||
|
||||
Reference in New Issue
Block a user