add PublicJwtService

This commit is contained in:
2025-01-01 02:03:55 +01:00
parent 90abefce22
commit 35d8d5dac4
3 changed files with 73 additions and 4 deletions

View File

@@ -6,11 +6,16 @@ In quiet chambers of learning, where minds are aglow, A ledger of endorsements,
The following properties can be used to configure the deployment of your application. If specified, these properties will load their respective services. The following properties can be used to configure the deployment of your application. If specified, these properties will load their respective services.
| name | info | | name | info |
|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------| |-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| jwt.private-key | Location of the private key file. If specified, the `PrivateJwtService` will be loaded with the provided private key for signing purposes. | | jwt.private-key | Location of the private key file. If specified, the `PrivateJwtService` will be loaded with the provided private key for signing purposes. |
| jwt.public-key | Location of the public key file. If specified, the `PublicJwtService` service will be loaded with the provided public key for verification purposes. |
**Note:** The `jwt.private-key` property is optional and corresponds to the `PrivateJwtService`. If specified, this service will be loaded for signing purposes. **Note:** The `jwt.private-key` and `jwt.public-key` properties are optional and correspond to separate services: `PrivateJwtService` and `PublicJwtService`, respectively. If either property is specified, its corresponding service will be loaded. For example:
- Specifying only `jwt.private-key` will load the `PrivateJwtService` for signing purposes.
- Specifying only `jwt.public-key` will load the `PublicJwtService` for verification purposes.
- Specifying both properties will enable both services, allowing for full JWT functionality with authentication and authorization.
## Releasing library ## Releasing library

View File

@@ -0,0 +1,28 @@
package ltd.hlaeja.jwt.service
import io.jsonwebtoken.Claims
import io.jsonwebtoken.Jws
import io.jsonwebtoken.JwtParser
import io.jsonwebtoken.Jwts
import ltd.hlaeja.jwt.util.PublicKeyProvider
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.stereotype.Service
@Service
@ConditionalOnProperty(prefix = "jwt", name = ["public-key"])
class PublicJwtService(
@Value("\${jwt.public-key}")
jwtPublicKey: String,
) {
private val parser: JwtParser = Jwts.parser()
.verifyWith(PublicKeyProvider.load(jwtPublicKey))
.build()
fun <T> verify(
token: String,
block: (claims: Jws<Claims>) -> T,
): T = parser.parseSignedClaims(token)
.let(block)
}

View File

@@ -0,0 +1,36 @@
package ltd.hlaeja.jwt.service
import java.nio.charset.StandardCharsets.UTF_8
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.core.io.ClassPathResource
import org.springframework.util.FileCopyUtils
class PublicJwtServiceTest {
private lateinit var service: PublicJwtService
@BeforeEach
fun setup() {
service = PublicJwtService("cert/valid-public-key.pem")
}
@Test
fun `parse token with claims`() {
// given
val token = String(FileCopyUtils.copyToByteArray(ClassPathResource("jwt.token").inputStream), UTF_8).trim()
// when
val result = service.verify(token) { claims ->
mapOf(
"claim1" to claims.payload["claim1"] as String,
"claim2" to claims.payload["claim2"] as Int,
)
}
// then
assertThat(result["claim1"]).isEqualTo("value1")
assertThat(result["claim2"]).isEqualTo(123)
}
}