All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.jwt.JWTValidator Maven / Gradle / Ivy

Go to download

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

There is a newer version: 5.8.34
Show newest version
package cn.hutool.jwt;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.NoneJWTSigner;

import java.util.Date;

/**
 * JWT数据校验器,用于校验包括:
 * 
    *
  • 算法是否一致
  • *
  • 算法签名是否正确
  • *
  • 字段值是否有效(例如时间未过期等)
  • *
* * @author looly * @since 5.7.2 */ public class JWTValidator { private final JWT jwt; /** * 创建JWT验证器 * * @param token JWT Token * @return JWTValidator */ public static JWTValidator of(String token) { return new JWTValidator(JWT.of(token)); } /** * 创建JWT验证器 * * @param jwt JWT对象 * @return JWTValidator */ public static JWTValidator of(JWT jwt) { return new JWTValidator(jwt); } /** * 构造 * * @param jwt JWT对象 */ public JWTValidator(JWT jwt) { this.jwt = jwt; } /** * 验证算法,使用JWT对象自带的{@link JWTSigner} * * @return this * @throws ValidateException 验证失败的异常 */ public JWTValidator validateAlgorithm() throws ValidateException { return validateAlgorithm(null); } /** * 验证算法,使用自定义的{@link JWTSigner} * * @param signer 用于验证算法的签名器 * @return this * @throws ValidateException 验证失败的异常 */ public JWTValidator validateAlgorithm(JWTSigner signer) throws ValidateException { validateAlgorithm(this.jwt, signer); return this; } /** * 检查JWT的以下三两个时间: * *
    *
  • {@link JWTPayload#NOT_BEFORE}:被检查时间必须晚于生效时间
  • *
  • {@link JWTPayload#EXPIRES_AT}:被检查时间必须早于失效时间
  • *
  • {@link JWTPayload#ISSUED_AT}:签发时间必须早于失效时间
  • *
*

* 如果某个时间没有设置,则不检查(表示无限制) * * @return this * @throws ValidateException 验证失败的异常 * @since 5.7.3 */ public JWTValidator validateDate() throws ValidateException { return validateDate(DateUtil.beginOfSecond(DateUtil.date())); } /** * 检查JWT的以下三两个时间: * *

    *
  • {@link JWTPayload#NOT_BEFORE}:生效时间不能晚于当前时间
  • *
  • {@link JWTPayload#EXPIRES_AT}:失效时间不能早于当前时间
  • *
  • {@link JWTPayload#ISSUED_AT}: 签发时间不能晚于当前时间
  • *
*

* 如果某个时间没有设置,则不检查(表示无限制) * * @param dateToCheck 被检查的时间,一般为当前时间 * @return this * @throws ValidateException 验证失败的异常 */ public JWTValidator validateDate(Date dateToCheck) throws ValidateException { validateDate(this.jwt.getPayload(), dateToCheck, 0L); return this; } /** * 检查JWT的以下三两个时间: * *

    *
  • {@link JWTPayload#NOT_BEFORE}:生效时间不能晚于当前时间
  • *
  • {@link JWTPayload#EXPIRES_AT}:失效时间不能早于当前时间
  • *
  • {@link JWTPayload#ISSUED_AT}: 签发时间不能晚于当前时间
  • *
*

* 如果某个时间没有设置,则不检查(表示无限制) * * @param dateToCheck 被检查的时间,一般为当前时间 * @param leeway 容忍空间,单位:秒。当不能晚于当前时间时,向后容忍;不能早于向前容忍。 * @return this * @throws ValidateException 验证失败的异常 */ public JWTValidator validateDate(Date dateToCheck, long leeway) throws ValidateException { validateDate(this.jwt.getPayload(), dateToCheck, leeway); return this; } /** * 验证算法 * * @param jwt {@link JWT}对象 * @param signer 用于验证的签名器 * @throws ValidateException 验证异常 */ private static void validateAlgorithm(JWT jwt, JWTSigner signer) throws ValidateException { final String algorithmId = jwt.getAlgorithm(); if (null == signer) { signer = jwt.getSigner(); } if (StrUtil.isEmpty(algorithmId)) { // 可能无签名 if (null == signer || signer instanceof NoneJWTSigner) { return; } throw new ValidateException("No algorithm defined in header!"); } if (null == signer) { throw new IllegalArgumentException("No Signer for validate algorithm!"); } final String algorithmIdInSigner = signer.getAlgorithmId(); if (false == StrUtil.equals(algorithmId, algorithmIdInSigner)) { throw new ValidateException("Algorithm [{}] defined in header doesn't match to [{}]!" , algorithmId, algorithmIdInSigner); } // 通过算法验证签名是否正确 if (false == jwt.verify(signer)) { throw new ValidateException("Signature verification failed!"); } } /** * 检查JWT的以下三两个时间: * *

    *
  • {@link JWTPayload#NOT_BEFORE}:生效时间不能晚于当前时间
  • *
  • {@link JWTPayload#EXPIRES_AT}:失效时间不能早于当前时间
  • *
  • {@link JWTPayload#ISSUED_AT}: 签发时间不能晚于当前时间
  • *
*

* 如果某个时间没有设置,则不检查(表示无限制) * * @param payload {@link JWTPayload} * @param now 当前时间 * @param leeway 容忍空间,单位:秒。当不能晚于当前时间时,向后容忍;不能早于向前容忍。 * @throws ValidateException 验证异常 */ private static void validateDate(JWTPayload payload, Date now, long leeway) throws ValidateException { if (null == now) { // 默认当前时间 now = DateUtil.date(); // truncate millis now.setTime(now.getTime() / 1000 * 1000); } // 检查生效时间(生效时间不能晚于当前时间) final Date notBefore = payload.getClaimsJson().getDate(JWTPayload.NOT_BEFORE); validateNotAfter(JWTPayload.NOT_BEFORE, notBefore, now, leeway); // 检查失效时间(失效时间不能早于当前时间) final Date expiresAt = payload.getClaimsJson().getDate(JWTPayload.EXPIRES_AT); validateNotBefore(JWTPayload.EXPIRES_AT, expiresAt, now, leeway); // 检查签发时间(签发时间不能晚于当前时间) final Date issueAt = payload.getClaimsJson().getDate(JWTPayload.ISSUED_AT); validateNotAfter(JWTPayload.ISSUED_AT, issueAt, now, leeway); } /** * 验证指定字段的时间不能晚于当前时间
* 被检查的日期不存在则跳过 * * @param fieldName 字段名 * @param dateToCheck 被检查的字段日期 * @param now 当前时间 * @param leeway 容忍空间,单位:秒。向后容忍 * @throws ValidateException 验证异常 */ private static void validateNotAfter(String fieldName, Date dateToCheck, Date now, long leeway) throws ValidateException { if (null == dateToCheck) { return; } if(leeway > 0){ now = DateUtil.date(now.getTime() + leeway * 1000); } if (dateToCheck.after(now)) { throw new ValidateException("'{}':[{}] is after now:[{}]", fieldName, DateUtil.date(dateToCheck), DateUtil.date(now)); } } /** * 验证指定字段的时间不能早于当前时间
* 被检查的日期不存在则跳过 * * @param fieldName 字段名 * @param dateToCheck 被检查的字段日期 * @param now 当前时间 * @param leeway 容忍空间,单位:秒。。向前容忍 * @throws ValidateException 验证异常 */ @SuppressWarnings("SameParameterValue") private static void validateNotBefore(String fieldName, Date dateToCheck, Date now, long leeway) throws ValidateException { if (null == dateToCheck) { return; } if(leeway > 0){ now = DateUtil.date(now.getTime() - leeway * 1000); } if (dateToCheck.before(now)) { throw new ValidateException("'{}':[{}] is before now:[{}]", fieldName, DateUtil.date(dateToCheck), DateUtil.date(now)); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy