11package cn .licoy .encryptbody .advice ;
22
33import cn .hutool .core .io .IoUtil ;
4+ import cn .hutool .core .util .ReflectUtil ;
45import cn .hutool .core .util .StrUtil ;
56import cn .hutool .crypto .SecureUtil ;
67import cn .hutool .crypto .asymmetric .RSA ;
8+ import cn .licoy .encryptbody .annotation .FieldBody ;
79import cn .licoy .encryptbody .annotation .decrypt .AESDecryptBody ;
810import cn .licoy .encryptbody .annotation .decrypt .DESDecryptBody ;
911import cn .licoy .encryptbody .annotation .decrypt .DecryptBody ;
1012import cn .licoy .encryptbody .annotation .decrypt .RSADecryptBody ;
11- import cn .licoy .encryptbody .annotation .encrypt .RSAEncryptBody ;
1213import cn .licoy .encryptbody .bean .DecryptAnnotationInfoBean ;
1314import cn .licoy .encryptbody .bean .DecryptHttpInputMessage ;
1415import cn .licoy .encryptbody .config .EncryptBodyConfig ;
1516import cn .licoy .encryptbody .enums .DecryptBodyMethod ;
1617import cn .licoy .encryptbody .exception .DecryptBodyFailException ;
1718import cn .licoy .encryptbody .exception .DecryptMethodNotFoundException ;
1819import cn .licoy .encryptbody .util .CommonUtils ;
20+ import com .fasterxml .jackson .databind .ObjectMapper ;
1921import lombok .extern .slf4j .Slf4j ;
2022import org .springframework .core .MethodParameter ;
2123import org .springframework .core .annotation .Order ;
2426import org .springframework .web .bind .annotation .ControllerAdvice ;
2527import org .springframework .web .servlet .mvc .method .annotation .RequestBodyAdvice ;
2628
27- import java .lang .annotation .Annotation ;
29+ import java .lang .reflect .AnnotatedElement ;
30+ import java .lang .reflect .Field ;
2831import java .lang .reflect .Method ;
2932import java .lang .reflect .Type ;
3033
@@ -44,25 +47,35 @@ public class DecryptRequestBodyAdvice implements RequestBodyAdvice {
4447
4548 private final EncryptBodyConfig config ;
4649
47- public DecryptRequestBodyAdvice (EncryptBodyConfig config ) {
50+ private final ObjectMapper objectMapper ;
51+
52+ public DecryptRequestBodyAdvice (ObjectMapper objectMapper , EncryptBodyConfig config ) {
53+ this .objectMapper = objectMapper ;
4854 this .config = config ;
4955 }
5056
5157 @ Override
5258 public boolean supports (MethodParameter methodParameter , Type targetType , Class <? extends HttpMessageConverter <?>> converterType ) {
53- Annotation [] annotations = methodParameter .getDeclaringClass ().getAnnotations ();
54- if (annotations .length > 0 ) {
55- for (Annotation annotation : annotations ) {
56- if (annotation instanceof DecryptBody || annotation instanceof AESDecryptBody || annotation instanceof DESDecryptBody || annotation instanceof RSADecryptBody ) {
59+ if (this .hasDecryptAnnotation (methodParameter .getDeclaringClass ())) {
60+ return true ;
61+ }
62+ Method method = methodParameter .getMethod ();
63+ if (method != null ) {
64+ if (this .hasDecryptAnnotation (method )) {
65+ return true ;
66+ }
67+ Class <?>[] parameterTypes = method .getParameterTypes ();
68+ for (Class <?> parameterType : parameterTypes ) {
69+ if (this .hasDecryptAnnotation (parameterType )) {
5770 return true ;
5871 }
5972 }
6073 }
61- Method method = methodParameter . getMethod () ;
62- if ( method == null ) {
63- return false ;
64- }
65- return method .isAnnotationPresent (DecryptBody .class ) || method .isAnnotationPresent (AESDecryptBody .class ) || method .isAnnotationPresent (DESDecryptBody .class ) || method .isAnnotationPresent (RSADecryptBody .class );
74+ return false ;
75+ }
76+
77+ private boolean hasDecryptAnnotation ( AnnotatedElement annotatedElement ) {
78+ return annotatedElement .isAnnotationPresent (DecryptBody .class ) || annotatedElement .isAnnotationPresent (AESDecryptBody .class ) || annotatedElement .isAnnotationPresent (DESDecryptBody .class ) || annotatedElement .isAnnotationPresent (RSADecryptBody .class );
6679 }
6780
6881 @ Override
@@ -81,12 +94,33 @@ public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodPara
8194 if (body == null || StrUtil .isEmpty (body )) {
8295 throw new DecryptBodyFailException ("The request body is NULL or an empty string, so the decryption failed." + " (请求正文为NULL或为空字符串,因此解密失败。)" );
8396 }
97+ Class <?> targetTypeClass ;
98+ try {
99+ targetTypeClass = Class .forName (targetType .getTypeName ());
100+ } catch (ClassNotFoundException e ) {
101+ throw new DecryptBodyFailException (e .getMessage ());
102+ }
84103 String decryptBody = null ;
85- DecryptAnnotationInfoBean methodAnnotation = this .getMethodAnnotation (parameter );
104+ DecryptAnnotationInfoBean methodAnnotation = this .getDecryptAnnotation (parameter . getMethod () );
86105 if (methodAnnotation != null ) {
87106 decryptBody = switchDecrypt (body , methodAnnotation );
107+ } else if (this .hasDecryptAnnotation (targetTypeClass )) {
108+ if (targetTypeClass .isAnnotationPresent (FieldBody .class )) {
109+ try {
110+ Object bodyInstance = objectMapper .readValue (body , targetTypeClass );
111+ Object decryptBodyInstance = this .eachClassField (bodyInstance , targetTypeClass );
112+ decryptBody = objectMapper .writeValueAsString (decryptBodyInstance );
113+ } catch (Exception e ) {
114+ throw new DecryptBodyFailException (e .getMessage ());
115+ }
116+ } else {
117+ DecryptAnnotationInfoBean classAnnotation = this .getDecryptAnnotation (targetTypeClass );
118+ if (classAnnotation != null ) {
119+ decryptBody = switchDecrypt (body , classAnnotation );
120+ }
121+ }
88122 } else {
89- DecryptAnnotationInfoBean classAnnotation = this .getClassAnnotation (parameter .getDeclaringClass ());
123+ DecryptAnnotationInfoBean classAnnotation = this .getDecryptAnnotation (parameter .getDeclaringClass ());
90124 if (classAnnotation != null ) {
91125 decryptBody = switchDecrypt (body , classAnnotation );
92126 }
@@ -106,69 +140,72 @@ public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodPa
106140 return body ;
107141 }
108142
143+ private Object eachClassField (Object body , Class <?> clazz ) {
144+ Field [] declaredFields = clazz .getDeclaredFields ();
145+ for (Field field : declaredFields ) {
146+ field .setAccessible (true );
147+ DecryptAnnotationInfoBean decryptAnnotation = this .getDecryptAnnotation (field );
148+ Class <?> type = field .getType ();
149+ if (decryptAnnotation != null ) {
150+ FieldBody fieldBody = field .getAnnotation (FieldBody .class );
151+ if (fieldBody != null ) {
152+ Field setField = ReflectUtil .getField (clazz , fieldBody .field ());
153+ if (setField != null && setField .getType ().equals (String .class )) {
154+ Object fieldValue = ReflectUtil .getFieldValue (body , setField );
155+ String decryptResult = this .switchDecrypt (String .valueOf (fieldValue ), decryptAnnotation );
156+ ReflectUtil .setFieldValue (body , field , decryptResult );
157+ }
158+ } else if (type .equals (String .class )) {
159+ String decryptResult = this .switchDecrypt (String .valueOf (ReflectUtil .getFieldValue (body , field )), decryptAnnotation );
160+ ReflectUtil .setFieldValue (body , field , decryptResult );
161+ }
162+ } else if (!CommonUtils .isConvertToString (type )) {
163+ Object fieldValue = ReflectUtil .getFieldValue (body , field );
164+ if (fieldValue != null ) {
165+ this .eachClassField (fieldValue , type );
166+ }
167+ }
168+ }
169+ return body ;
170+ }
171+
109172 /**
110- * 获取方法控制器上的加密注解信息
173+ * 获取解密注解的数据
111174 *
112- * @param methodParameter 控制器方法
113- * @return 加密注解信息
175+ * @param annotatedElement 注解元素
176+ * @return 解密注解组装数据
114177 */
115- private DecryptAnnotationInfoBean getMethodAnnotation (MethodParameter methodParameter ) {
116- Method method = methodParameter .getMethod ();
117- if (method == null ) {
178+ private DecryptAnnotationInfoBean getDecryptAnnotation (AnnotatedElement annotatedElement ) {
179+ if (annotatedElement == null ) {
118180 return null ;
119181 }
120- if (method .isAnnotationPresent (DecryptBody .class )) {
121- DecryptBody decryptBody = methodParameter . getMethodAnnotation (DecryptBody .class );
182+ if (annotatedElement .isAnnotationPresent (DecryptBody .class )) {
183+ DecryptBody decryptBody = annotatedElement . getAnnotation (DecryptBody .class );
122184 if (decryptBody != null ) {
123185 return DecryptAnnotationInfoBean .builder ().decryptBodyMethod (decryptBody .value ()).key (decryptBody .otherKey ()).build ();
124186 }
125187 }
126- if (method .isAnnotationPresent (DESDecryptBody .class )) {
127- DESDecryptBody decryptBody = methodParameter . getMethodAnnotation (DESDecryptBody .class );
188+ if (annotatedElement .isAnnotationPresent (DESDecryptBody .class )) {
189+ DESDecryptBody decryptBody = annotatedElement . getAnnotation (DESDecryptBody .class );
128190 if (decryptBody != null ) {
129191 return DecryptAnnotationInfoBean .builder ().decryptBodyMethod (DecryptBodyMethod .DES ).key (decryptBody .key ()).build ();
130192 }
131193 }
132- if (method .isAnnotationPresent (AESDecryptBody .class )) {
133- AESDecryptBody decryptBody = methodParameter . getMethodAnnotation (AESDecryptBody .class );
194+ if (annotatedElement .isAnnotationPresent (AESDecryptBody .class )) {
195+ AESDecryptBody decryptBody = annotatedElement . getAnnotation (AESDecryptBody .class );
134196 if (decryptBody != null ) {
135197 return DecryptAnnotationInfoBean .builder ().decryptBodyMethod (DecryptBodyMethod .AES ).key (decryptBody .key ()).build ();
136198 }
137199 }
138- if (method .isAnnotationPresent (RSADecryptBody .class )) {
139- RSADecryptBody decryptBody = methodParameter . getMethodAnnotation (RSADecryptBody .class );
200+ if (annotatedElement .isAnnotationPresent (RSADecryptBody .class )) {
201+ RSADecryptBody decryptBody = annotatedElement . getAnnotation (RSADecryptBody .class );
140202 if (decryptBody != null ) {
141203 return DecryptAnnotationInfoBean .builder ().decryptBodyMethod (DecryptBodyMethod .RSA ).key (decryptBody .key ()).rsaKeyType (decryptBody .type ()).build ();
142204 }
143205 }
144206 return null ;
145207 }
146208
147- /**
148- * 获取类控制器上的加密注解信息
149- *
150- * @param clazz 控制器类
151- * @return 加密注解信息
152- */
153- private DecryptAnnotationInfoBean getClassAnnotation (Class <?> clazz ) {
154- Annotation [] annotations = clazz .getDeclaredAnnotations ();
155- if (annotations .length > 0 ) {
156- for (Annotation annotation : annotations ) {
157- if (annotation instanceof DecryptBody ) {
158- DecryptBody decryptBody = (DecryptBody ) annotation ;
159- return DecryptAnnotationInfoBean .builder ().decryptBodyMethod (decryptBody .value ()).key (decryptBody .otherKey ()).build ();
160- }
161- if (annotation instanceof DESDecryptBody ) {
162- return DecryptAnnotationInfoBean .builder ().decryptBodyMethod (DecryptBodyMethod .DES ).key (((DESDecryptBody ) annotation ).key ()).build ();
163- }
164- if (annotation instanceof AESDecryptBody ) {
165- return DecryptAnnotationInfoBean .builder ().decryptBodyMethod (DecryptBodyMethod .AES ).key (((AESDecryptBody ) annotation ).key ()).build ();
166- }
167- }
168- }
169- return null ;
170- }
171-
172209
173210 /**
174211 * 选择加密方式并进行解密
0 commit comments