Skip to content

Commit

Permalink
refactor: NativePRNGNonBlocking SecureRandom 사용
Browse files Browse the repository at this point in the history
  • Loading branch information
suw0n committed Jul 30, 2024
1 parent dc5f6c1 commit 9a51e6a
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 54 deletions.
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
kotlin("plugin.spring") version "1.8.22"
}

val jjwtVersion = "0.11.5"
val jjwtVersion = "0.12.6"

group = "b1nd"
version = "0.0.1-SNAPSHOT"
Expand Down Expand Up @@ -42,7 +42,7 @@ dependencies {

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
freeCompilerArgs = freeCompilerArgs + "-Xjsr305=strict"
jvmTarget = "17"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import b1nd.tokenserver.application.auth.usecase.data.*
import b1nd.tokenserver.domain.auth.TokenType
import b1nd.tokenserver.domain.auth.Token
import b1nd.tokenserver.domain.auth.exception.WrongTokenTypeException
import b1nd.tokenserver.application.common.async.AsyncCPUBoundTask
import b1nd.tokenserver.application.common.data.response.BaseResponse
import org.springframework.stereotype.Component
import reactor.core.publisher.Mono
Expand All @@ -15,32 +14,32 @@ class AuthUseCase(val tokenPort: TokenPort) {

fun issueAccessToken(request: IssueTokenRequest): Mono<BaseResponse<TokenResponse>> {
return issueToken(request, TokenType.ACCESS)
.map { result -> BaseResponse.ok("Access 토큰 발급 성공", result) }
.map { data -> BaseResponse.ok("Access 토큰 발급 성공", data) }
}

fun reissueAccessToken(request: ReissueAccessTokenRequest): Mono<BaseResponse<TokenResponse>> {
return AsyncCPUBoundTask.execute {
return Mono.fromCallable {
val token: Token = tokenPort.parse(request.refreshToken, TokenType.REFRESH)
if(token.isNotRefreshToken()) {
throw WrongTokenTypeException
}
TokenResponse(tokenPort.issue(token.memberId, token.accessLevel, TokenType.ACCESS))
}.map { token -> BaseResponse.ok("Access 토큰 재발급 성공", token) }
}.map { data -> BaseResponse.ok("Access 토큰 재발급 성공", data) }
}

fun issueRefreshToken(request: IssueTokenRequest): Mono<BaseResponse<TokenResponse>> {
return issueToken(request, TokenType.REFRESH)
.map { result -> BaseResponse.ok("Refresh 토큰 발급 성공", result) }
.map { data -> BaseResponse.ok("Refresh 토큰 발급 성공", data) }
}

private fun issueToken(request: IssueTokenRequest, type: TokenType): Mono<TokenResponse> {
return AsyncCPUBoundTask.execute {
return Mono.fromCallable {
TokenResponse(tokenPort.issue(request.memberId, request.accessLevel, type))
}
}

fun verifyToken(request: VerifyTokenRequest): Mono<BaseResponse<VerifyTokenResponse>> {
return AsyncCPUBoundTask.execute {
return Mono.fromCallable {
val token: Token = tokenPort.parse(request.token, TokenType.ACCESS)
VerifyTokenResponse(token.memberId, token.accessLevel, 0)
}.map { info -> BaseResponse.ok("토큰 검증 성공", info) }
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,36 @@ import io.jsonwebtoken.security.Keys
import org.springframework.stereotype.Component
import java.lang.IllegalArgumentException
import java.nio.charset.StandardCharsets
import java.security.SecureRandom
import java.util.*

@Component
class JWTAdapter(val jwtProperties: JWTProperties): TokenPort {
class JwtAdapter(private val helper: JwtHelper): TokenPort {

override fun issue(memberId: String, accessLevel: Int, type: TokenType): String {
val secret: String
val expiryDate: Long
when (type) {
TokenType.ACCESS -> {
secret = jwtProperties.accessSecret
expiryDate = jwtProperties.accessExpiryDate
}
private val secureRandom = SecureRandom.getInstance("NativePRNGNonBlocking")

TokenType.REFRESH -> {
secret = jwtProperties.refreshSecret
expiryDate = jwtProperties.refreshExpiryDate
}
}
override fun issue(memberId: String, accessLevel: Int, type: TokenType): String {
val (secret, expiryDate) = helper.getSecretAndExpiry(type)
return Jwts.builder()
.signWith(Keys.hmacShaKeyFor(secret.toByteArray(StandardCharsets.UTF_8)), SignatureAlgorithm.HS256)
.setSubject(type.name)
.signWith(Keys.hmacShaKeyFor(secret.toByteArray(StandardCharsets.UTF_8)), Jwts.SIG.HS256)
.subject(type.name)
.claim("memberId", memberId)
.claim("accessLevel", accessLevel)
.setIssuedAt(Date())
.setExpiration(Date(System.currentTimeMillis() + expiryDate))
.issuedAt(Date())
.expiration(Date(System.currentTimeMillis() + expiryDate))
.apply {
random(secureRandom)
}
.compact()
}

override fun parse(token: String, type: TokenType): Token {
return try {
val secret: String = when (type) {
TokenType.ACCESS -> jwtProperties.accessSecret
TokenType.REFRESH -> jwtProperties.refreshSecret
}
val claims: Jws<Claims> = Jwts.parserBuilder().setSigningKey(Keys.hmacShaKeyFor(secret.toByteArray())).build().parseClaimsJws(token)
val claims: Jws<Claims> = helper.getParser(type).parseSignedClaims(token)
Token(
claims.body["memberId"] as String,
claims.body["accessLevel"] as Int,
TokenType.of(claims.body.subject)
claims.payload["memberId"] as String,
claims.payload["accessLevel"] as Int,
TokenType.of(claims.payload.subject)
)
} catch (e: Exception) {
when (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package b1nd.tokenserver.infrastructure.adapter.driven.jwt
import org.springframework.boot.context.properties.ConfigurationProperties

@ConfigurationProperties(prefix = "jwt")
data class JWTProperties(
data class JwtProperties(

val accessSecret: String,
val refreshSecret: String,
Expand Down

0 comments on commit 9a51e6a

Please sign in to comment.