2

パッケージを使用して、特定の keyId の公開鍵を JWK 形式で返す REST 認証サーバーを実装しましたcom.nimbusds:nimbus-jose-jwt:9.13。コードは次のようになります。

@RequestMapping(value = "/oauth2", produces = APPLICATION_JSON_VALUE)
public interface Rest {
...
    @GetMapping("/public-key/{keyId}")
    @Operation(summary = "Return the public key corresponding to the key id")
    JWK getPublicKey(@PathVariable String keyId);
}

public class RestController implements Rest {
.....
 public JWK getPublicKey(String keyId) {
         byte[] publicKeyBytes = ....
         RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));
         JWK jwk = new RSAKey.Builder(publicKey)
                .keyID(keyId)
                .algorithm(new Algorithm(publicKey.getAlgorithm()))
                .keyUse(KeyUse.SIGNATURE)
                .build();
         return jwk;
    }
}

このコードは、次の形式で JWK キーを返します。

{
    "keyStore": null,
    "private": false,
    "publicExponent": {},
    "modulus": {},
    "firstPrimeFactor": null,
    "secondPrimeFactor": null,
    "firstFactorCRTExponent": null,
    "secondFactorCRTExponent": null,
    "firstCRTCoefficient": null,
    "otherPrimes": [],
    "requiredParams": {
        "e": "some-valid-exponent",
        "kty": "RSA",
        "n": "some-valid-modulus"
    },
    "privateExponent": null,
    "x509CertChain": null,
    "algorithm": {
        "name": "RSA",
        "requirement": null
    },
    "keyOperations": null,
    "keyID": "some-valid-key-id",
    "x509CertURL": null,
    "x509CertThumbprint": null,
    "x509CertSHA256Thumbprint": null,
    "parsedX509CertChain": null,
    "keyUse": {
        "value": "sig"
    },
    "keyType": {
        "value": "RSA",
        "requirement": "REQUIRED"
    }
}

クライアント側 (Java) で、次のコードを使用して jwk を解析しようとします。

public JWK getPublicKey(String keyId) {
 String json = restTemplate.getForObject(publicUrl + "/oauth2/public-key/" + keyId, String.class);
        try {
            return JWK.parse(json);
        } catch (ParseException e) {
            log.error("Unable to parse JWK", e);
            return null;
        }
}

parseただし、 が例外をスローするため、クライアントはキーを解析できません( Missing parameter "kty")。メインの JWT josn 本体にキーがJWK.parse必要ですが、デフォルトのシリアル化ではキーがキー内に埋め込まれます。試してみると、メインのjson本体にキーが表示されます。ktyJWKktyrequiredParamsjwk.toString()kty

ネイティブ JWK オブジェクトのシリアル化/逆シリアル化が単純な方法で機能しないのはなぜですか? カスタム jwt 構造またはシリアライザー/デシリアライザーを実装せずにこれを修正する最良の方法は何でしょうか?

更新 1 : このコードは、戻り値の型JWKMap<String, Object>orに変更Stringし、クライアント側で逆シリアル化を処理する場合に機能します。ただし、パッケージがネイティブに (デ) シリアル化を行う方がよいでしょう。

4

1 に答える 1