У меня есть приложение quarkus, которое само не генерирует токены jwt, но обладает секретным ключом токенов с подписью HS256 (qwertyuiopasdfghjklzxcvbnm123456). Мне нужно проверить токены входящих сетевых запросов, но для каждого запроса я получаю сообщение об ошибке:
io.smallrye.jwt.auth.principal.ParseException: SRJWT07000: Failed to verify a token
...
Caused by: org.jose4j.jwt.consumer.InvalidJwtSignatureException: JWT rejected due to invalid signature. Additional details: [[9] Invalid JWS Signature: JsonWebSignature{"typ":"JWT","alg":"HS256"}->eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE2NjczODI2NzIsImV4cCI6MTY5ODkxODY3MiwiYXVkIjoid3d3LmV4YW1wbGUuY29tIiwic3ViIjoianJvY2tldEBleGFtcGxlLmNvbSIsIkdpdmVuTmFtZSI6IkpvaG5ueSIsIlN1cm5hbWUiOiJSb2NrZXQiLCJFbWFpbCI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJSb2xlIjpbIk1hbmFnZXIiLCJQcm9qZWN0IEFkbWluaXN0cmF0b3IiXX0.5vBHzbTKjLnAkAIYuA3c50nWV--o9jIWV2i0GZI-aw4]
Мой application.properties конфиг:
smallrye.jwt.verify.key-format=JWK
smallrye.jwt.verify.key.location=JWTSecret.jwk
smallrye.jwt.verify.algorithm=HS256
quarkus.native.resources.includes=JWTSecret.jwk
JWTSecret.jwk
{
"kty": "oct",
"k": "qwertyuiopasdfghjklzxcvbnm123456",
"alg": "HS256"
}
Я попытался проверить подпись токена с помощью jwt.io, используя секретный ключ выше (и он отлично проверил подпись), поэтому я предполагаю, что что-то не так с моим файлом JWK или конфигурацией application.properties. Я также попробовал алгоритм проверки RS256 (с открытыми/закрытыми pem-ключами), и он работал нормально, но, к сожалению, мне нужно, чтобы он работал с HS256.
Код ниже, но все должно быть в порядке, так как он отлично работает с другими алгоритмами проверки.
package co.ogram.domain
import org.eclipse.microprofile.jwt.JsonWebToken
import javax.annotation.security.RolesAllowed
import javax.enterprise.inject.Default
import javax.inject.Inject
import javax.ws.rs.*
import javax.ws.rs.core.Context
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.SecurityContext
@Path("/secured")
class TokenSecuredResource {
@Inject
@field:Default
var jwt: JsonWebToken? = null
@GET
@Path("/roles-allowed")
@RolesAllowed("Admin")
@Produces(MediaType.TEXT_PLAIN)
fun helloRolesAllowed(@Context ctx: SecurityContext): String? {
return getResponseString(ctx!!)
}
private fun getResponseString(ctx: SecurityContext): String {
val name: String
name = if (ctx.userPrincipal == null) {
"anonymous"
} else if (ctx.userPrincipal.name != jwt!!.name) {
throw InternalServerErrorException("Principal and JsonWebToken names do not match")
} else {
ctx.userPrincipal.name
}
val type = jwt!!.getClaim<Int>("type")
return String.format(
"hello + %s,"
+ " isHttps: %s,"
+ " authScheme: %s,"
+ " type: %s,"
+ " hasJWT: %s",
name, ctx.isSecure, ctx.authenticationScheme, type, hasJwt()
)
}
private fun hasJwt(): Boolean {
return jwt!!.claimNames != null
}
}





Пакет jose4j выполняет правильную проверку с учетом JWK в качестве входных данных.
Ваш JWT подписан настоящими октетами jwk.k ("qwertyuiopasdfghjklzxcvbnm123456").
На самом деле вы должны base64url декодировать k, чтобы получить буфер для использования в качестве секрета HS256 для подписи. Это будет соответствовать тому, что делает пакет jose4j (что правильно).