web-dev-qa-db-ja.com

JWT署名がローカルで計算された署名と一致しません

私は使っている

JwtBuilder builder = Jwts.builder()
                    .setId(user.getEmail())
                    .signWith(signatureAlgorithm, signingKey);

トークンを作成するには

Jwts.parser().setSigningKey(secret).parse(token);

認証する。これをJUnitテストで実行すると、正常に機能します。ただし、ヘッダーとしてREST呼び出しで渡されたトークンを認証すると、SignatureExceptionで認証が失敗します。HTTP呼び出しの両端でトークンを検証しました。トークン文字列は同一です。/authenticateは静的であるため、それぞれの側で秘密は同じです。

9
stanlick

static Key secret = MacProvider.generateKey();は、クラスがロードされるときに静的変数が初期化されるため、サーバーがリロードされるたびに新しいランダムキーを生成します

つまり、JWTを発行する場合、サーバーが再起動しない限り有効になります。 SignatureExceptionは、署名キーが異なるためです

最初の生成後に署名キーsecret.getEncoded()を保存し、モジュールの起動時にそれをロードする必要があります

9
pedrofb

同様の問題がありました。私の場合、それは間違ったトークン検証でした。バイトとして符号を設定します。

.signWith(SignatureAlgorithm.HS512, jwtConfig.getSecret().getBytes())

しかし、トークンを解析してsignKeyを設定しているとき、バイトではなく文字列として設定しました。

Jwts.parser().setSigningKey(signingKey).parseClaimsJws(this.token)

また、トークンをチェックするときは常に引用符とスペースをチェックします。多くの場合、トークンの開始/終了に余分なスペース/引用符があります(trim()メソッドを使用)

2
S.Dayneko

同様の問題がありました。私の場合、両方のキーは同じですが、何らかの理由で引用符で囲まれたトークンを受け取りました(たとえば、"Syasda.da3das.aDjty6"ではなくSyasda.da3das.aDjty6)。

ほとんどの場合、jwt.ioでのテスト中に、ブラケットを確認せずにトークンを手動でコピーするため、これを実現するのに非常に時間がかかりました。

token = token.replace("\"",""); 

これらの引用符を削除することで問題は解決しました。これが他の人にも役立つことを願っています。

1
Nuper

同じ問題が発生しました。ソースでは、署名キーを変換するたびに、UTF-8エンコーディングを明示的に指定していることに気付きました。私は両方のトークンをデコードしながらエンコードを変更しようとしました:

 private Jws<Claims> decodeToken(String token) {
        return Jwts.parser()
                .setSigningKey(securityProperties.getTokenSecret().getBytes(Charset.forName("UTF-8")))
                .parseClaimsJws(token);
 }

そして、トークンに署名するとき:

private String getSignedToken(UserDetailsAdapter user, List<String> roles, byte[] signingKey) {
        return Jwts.builder()
                .signWith(Keys.hmacShaKeyFor(signingKey), SignatureAlgorithm.HS512)
                .setHeaderParam("typ", securityProperties.getTokenType())
                .setIssuer(guiServerSecurityProperties.getTokenIssuer())
                .setAudience(guiServerSecurityProperties.getTokenAudience())
                .setSubject(user.getUsername())
                .setExpiration(new Date(System.currentTimeMillis() + 864000000))
                .claim("rol", roles)
                .compact();
    }

これは私にとってこれを修正した唯一のものです。

1

URL REST=エンドポイント内のホストを変更する問題を解決しました。エラーHTTP 401不正が返された誤ったホストがありました。

0
jis83