Commit 8fbabb83 by 罗长华

增加签名包

parent b15cc7cd
package io.geekidea.springbootplus.framework.signature;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 签名注解
* 指定哪些接口或者哪些实体需要签名
* @Author linux
* @Date 2021年01月20日 08:32:00
* @Version 1.0
*/
@Target({TYPE, METHOD})
@Retention(RUNTIME)
@Documented
public @interface Signature {
/**
* 按照order值排序
*/
String ORDER_SORT = "ORDER_SORT";
/**
* 字典序排序
*/
String ALPHA_SORT = "ALPHA_SORT";
boolean resubmit() default true;
String sort() default Signature.ALPHA_SORT;
}
package io.geekidea.springbootplus.framework.signature;
/**
*
* @Author linux
* @Date 2021年01月20日 18:00
* @Version 1.0
*/
public class SignatureException extends RuntimeException {
/**
*
* @Author linux
* @Date 2021年01月20日 06:01:17
* @Version 1.0
*/
public SignatureException(String code) {
super(code);
}
public SignatureException(String code, String message) {
super(code + ":" + message);
}
}
package io.geekidea.springbootplus.framework.signature;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 签名字段
* 指定哪些字段需要签名
* @Author linux
* @Date 2021年01月20日 08:43:28
* @Version 1.0
*/
@Target({FIELD})
@Retention(RUNTIME)
@Documented
public @interface SignatureField {
//签名顺序
int order() default 0;
//字段name自定义值
String customName() default "";
//字段value自定义值
String customValue() default "";
}
package io.geekidea.springbootplus.framework.signature;
import lombok.Data;
import lombok.ToString;
import java.util.Set;
import javax.validation.constraints.NotBlank;
import org.springframework.boot.context.properties.ConfigurationProperties;
import com.google.common.collect.Sets;
/**
* 签名头信息类
* @Author linux
* @Date 2021年01月20日 16:28
* @Version 1.0
*/
@ConfigurationProperties(prefix = "can.signature")
@Signature
@Data
@ToString
public class SignatureHeaders {
public static final String SIGNATURE_HEADERS_PREFIX = "can-signature-";
public static final Set<String> SIGNATURE_HEADER_SET = Sets.newHashSet();
private static final String HEADER_APP_ID = SIGNATURE_HEADERS_PREFIX + "appid";
private static final String HEADER_TIMESTAMP = SIGNATURE_HEADERS_PREFIX + "timestamp";
private static final String HEADER_NONCE = SIGNATURE_HEADERS_PREFIX + "nonce";
private static final String HEADER_SIGNATURE = SIGNATURE_HEADERS_PREFIX + "signature";
static {
SIGNATURE_HEADER_SET.add(HEADER_APP_ID);
SIGNATURE_HEADER_SET.add(HEADER_TIMESTAMP);
SIGNATURE_HEADER_SET.add(HEADER_NONCE);
SIGNATURE_HEADER_SET.add(HEADER_SIGNATURE);
}
/**
* 线下分配的值
* 客户端和服务端各自保存appId对应的appSecret
*/
@NotBlank(message = "Header中缺少" + HEADER_APP_ID)
@SignatureField
private String appid;
/**
* 线下分配的值
* 客户端和服务端各自保存,与appId对应
*/
@SignatureField
private String appsecret;
/**
* 时间戳,单位: ms
*/
@NotBlank(message = "Header中缺少" + HEADER_TIMESTAMP)
@SignatureField
private String timestamp;
/**
* 流水号【防止重复提交】; (备注:针对查询接口,流水号只用于日志落地,便于后期日志核查; 针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求)
*/
@NotBlank(message = "Header中缺少" + HEADER_NONCE)
@SignatureField
private String nonce;
/**
* 签名
*/
@NotBlank(message = "Header中缺少" + HEADER_SIGNATURE)
private String signature;
}
package io.geekidea.springbootplus.framework.signature;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Jwt参数配置
* @Author linux
* @Date 2020年12月28日 11:25:17
* @Version 1.0
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "signature")
public class SignatureProperties {
/**
* appSecret
*/
private String appId;
/**
* appSecret
*/
private String appSecret;
/**
* 同一个nonce 请求多长时间内不允许重复请求 单位:秒
*/
private Long expireTime;
/**
* 同一个请求多长时间内有效 单位:秒
*/
private Long resubmitDuration;
}
package io.geekidea.springbootplus.framework.signature;
import java.util.Iterator;
import java.util.Optional;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.HibernateValidator;
/**
*
* @Author linux
* @Date 2021年01月20日 18:18
* @Version 1.0
*/
public class ValidatorUtils {
private final static Validator VALIDATOR_FAST =
Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();
private final static Validator VALIDATOR_ALL =
Validation.byProvider(HibernateValidator.class).configure().failFast(false).buildValidatorFactory().getValidator();
/**
* 校验遇到第一个不合法的字段直接返回不合法字段,后续字段不再校验
* @Time 2020年6月22日 上午11:36:13
* @param <T>
* @param domain
* @return
*/
public static <T> Optional<String> validateFast(T domain) {
Set<ConstraintViolation<T>> validateResult = VALIDATOR_FAST.validate(domain);
if (validateResult.size() > 0) {
System.out.println(validateResult.iterator().next().getPropertyPath() + ":" + validateResult.iterator().next().getMessage());
}
StringBuilder sb = new StringBuilder();
for (Iterator<ConstraintViolation<T>> iterator = validateResult.iterator(); iterator.hasNext(); ) {
sb.append(iterator.next().getMessage());
if (iterator.hasNext()) {
sb.append(" ,");
}
}
return Optional.of(sb.toString());
}
/**
* 校验所有字段并返回不合法字段
* @Time 2020年6月22日 上午11:36:55
* @param <T>
* @param domain
* @return
*/
public static <T> Optional<String> validateAll(T domain) {
Set<ConstraintViolation<T>> validateResult = VALIDATOR_ALL.validate(domain);
if (validateResult.size() > 0) {
for (ConstraintViolation<T> cv : validateResult) {
System.out.println(cv.getPropertyPath() + ":" + cv.getMessage());
}
}
StringBuilder sb = new StringBuilder();
for (Iterator<ConstraintViolation<T>> iterator = validateResult.iterator(); iterator.hasNext(); ) {
sb.append(iterator.next().getMessage());
if (iterator.hasNext()) {
sb.append(" ,");
}
}
return Optional.of(sb.toString());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment