我需要在使用 Java 中的 CAS 构建的 SSO 中添加 PHP 应用程序。用户身份验证后,SSO 将凭据发送到 PHP 应用程序,并使用以下代码构建令牌:
public function getToken(Signer $signer = null, Key $key = null)
{
$signer = $signer ?: $this->signer;
$key = $key ?: $this->key;
if ($signer instanceof Signer) {
$signer->modifyHeader($this->headers);
}
$payload = [
$this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->headers)),
$this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->claims))
];
$signature = $this->createSignature($payload, $signer, $key);
if ($signature !== null) {
$payload[] = $this->encoder->base64UrlEncode($signature);
}
return new Token($this->headers, $this->claims, $signature , $payload);
}
private function createSignature(array $payload, Signer $signer = null, Key $key = null)
{
if ($signer === null || $key === null) {
return null;
}
return $signer->sign(implode('.', $payload), $key);
}
因此,我尝试使用 java 验证生成的令牌,如下所示:
public boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
log.info("Invalid JWT signature.");
log.trace("Invalid JWT signature trace: {}", e);
e.printStackTrace();
}
....
}
为了验证签名,jjwt 拆分了令牌的 3 个部分,并尝试使用令牌标头中提供的算法对前 2 个部分进行签名。此步骤与创建令牌时用于创建令牌的签名相同。理论上,在创建和验证这两个步骤中使用相同的算法、paylod 和 secret,签名应该是相同的。但它不会发生。抛出以下异常:
io.jsonwebtoken.SignatureException:JWT 签名与本地计算的签名不匹配。JWT 有效性不能被断言,也不应该被信任。