免責事項:この記事はCC 4.0 BY-SAの著作権契約書に従って、ブロガーオリジナル記事です、複製、元のソースのリンクと、この文を添付してください。
このリンクします。https://blog.csdn.net/xxssyyyyssxx/article/details/88219298
プロジェクトが表示さhttps://gitee.com/xxssyyyyssxx/affect-inoutput
インターフェイスは、セキュリティを強化するために、当社の顧客と対話するために、我々はなく、すべてのインターフェイスの、暗号化(リクエストパラメータの暗号化、サーバーの暗号解読)、リターン情報の暗号化(サーバー側の暗号化、クライアント暗号解読)をインタフェースする必要があるかもしれませんこのすべては、いくつかのインタフェースは、我々は簡単に、この要件を満たすために、アノテーションを使用することができ、必要ないかもしれません。
暗号化と復号化と別の暗号化および復号化のインターフェイスパラメータを返すは、注釈は、要件を満たすために、暗号化および復号化のニーズかどうかを決定すること、すべての要求を傍受するControllerAdviceコントローラを使用して定義されています。
用法:DecryptRequestとEncryptResponse注釈が偽であるのいずれかが行われず、コントローラのクラスおよびメソッド上に配置することができます。このように:
@RestController
@RequestMapping( "/テスト")
// @ DecryptRequest
@EncryptResponse
パブリッククラスTestController {
@Autowired
@Qualifier( "rrCrypto")
プライベート暗号暗号;
(falseに)@DecryptRequest
(falseに)@EncryptResponse
@RequestMapping(値= "/ ENC"、メソッド= RequestMethod.POST)
パブリック文字列ENC(@RequestBody文字列本体){
戻りcrypto.encrypt(本体);
}
}
カスタムパラメータは、注釈、DecryptRequestを解読しました。
/ **
*復号注釈
*
* <P>このアノテーション追加インターフェイス(真)データ復号動作(POSTの本体)があってもよい
。</ P>の方法で配置されるクラスに*
* @author xiongshiyan
* /
@Target({ElementType.METHOD、ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
公共@interface DecryptRequest {
/ **
*か復号化ボディに
* /
真のブール値()デフォルト;
}
定義リターン情報暗号化されたノート、EncryptResponse。
/ **
*コメント暗号化
*
このアノテーション追加インターフェイス(真の)データの暗号化操作が* <P>
*クラスに配置することができ、この方法は、</ P>上に配置することができる
発現* @authorクマ詩
* /
@Targetを( ElementType.METHOD {、} ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
公共@interface {EncryptResponse
/ **
*暗号化の結果であれば
* /
ブール値()をtrueにデフォルト;
}
この注釈は、2つのカテゴリに配置することができますそして方法はすなわち、同じロジックを次の:&&注釈クラスメソッドの注釈、真実ではないものを、偽、偽です。メインロジックNeedCryptoで。
/ **
*暗号化と復号化のかどうかが決定される
2018年8月30日AT * @author xiongshiyan、[email protected]メール私と連絡や電話番号15208384257に
* /
クラスNeedCrypto {
プライベートNeedCrypto(){}
/ **
のため*必要結果の暗号化は、
ラベルやクラス1メソッドにマークされ、そしてtrueにされている
偽の上で暗号化されていない著しい必要がある2. *
* /
静的ブールneedEncrypt(MethodParameter戻り値の){
ブール暗号化= falseを、
ブールclassPresentAnno = returnType.getContainingClass ().isAnnotationPresent(EncryptResponse.class);
。=ブールmethodPresentAnno returnType.getMethod()isAnnotationPresent(EncryptResponse.class);
IF(classPresentAnno){
暗号化が//クラス必要とされているかどうかにマーク
= returnType.getContainingClass暗号化()getAnnotation(EncryptResponse.class).Valueのは();.
//クラスは、暗号化しない、暗号化なしすべての
IF(暗号化!){
falseに復帰;
}
}
IF(methodPresentAnno){
//メソッドにマーク暗号化する必要があるか否かを
暗号= returnType.getMethod()getAnnotation(EncryptResponse.class).Valueの();.
}
暗号化を返す;
}
/ **
*パラメータを復号化する必要が
ラベル1クラスまたはメソッドにマークされ、そしてされていますtrueに
* 2.必要がない偽標識復号
* /
静的ブールneedDecrypt(MethodParameterパラメータ){
ブール暗号= FALSEと、
classPresentAnno = parameter.getContainingClassブール()isAnnotationPresent(DecryptRequest.class);.
ブールmethodPresentAnno = parameter.getMethod()isAnnotationPresent(DecryptRequest.class);.
IF(classPresentAnno){
復号化するために、クラス//必要にマーク
暗号化=パラメータ。 getContainingClass()getAnnotation(DecryptRequest.class).Valueの();.
//クラスはすべて暗号化されず、暗号化されません
IF(暗号化!){
falseに復帰;
}
}
(methodPresentAnno)のiF {
メソッドを復号化するかどうかにマーク@
= parameter.getMethod暗号化()getAnnotation(DecryptRequest.class).Valueの();.
}
暗号化を返します。
}
}
次にControllerAdvice、復号化のための要求を定義し、RequestBodyAdvice実現DecryptRequestBodyAdviceを、定義されました。
/ **
*要求データを処理するベース<BR>を受信
*
方法@Decrypt操作<BR>を復号化データを追加するため*
*
*パラメータのみ@RequestBody有効です
* @author xiongshiyan
* /
@ControllerAdvice
@ConditionalOnProperty(接頭辞= "spring.crypto.request.decrypt"、名前=)=真matchIfMissingに、 "真の" havingValue =、 "有効"
publicクラスDecryptRequestBodyAdvice実装RequestBodyAdvice {
@value(「{$ spring.crypto.request.decrypt.charset:UTF } 8 ")。
プライベート文字列のcharset =" UTF-8 ";
@Autowired
@Qualifier(" rrCrypto「)
プライベート暗号クリプト;
@Override
パブリックブール支持体(MethodParameter MethodParameter、タイプたtargetType、
クラス<??HttpMessageConverter <>> converterType){拡張
trueを返します。
}
@Override
パブリックオブジェクトhandleEmptyBody(オブジェクト本体、HttpInputMessage inputMessage、MethodParameterパラメータ、
{?タイプたtargetType、クラス<HttpMessageConverter <>> converterType延び)
戻り体が、
}
@Override
公共HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage、MethodParameterパラメータ、タイプたtargetType、
クラス<?延びHttpMessageConverter <?>> converterType)がスローにIOException {
IF(NeedCrypto.needDecrypt(パラメータ)){
新しいDecryptHttpInputMessageを返す(inputMessage、文字セット、暗号化) ;
}
戻りinputMessage;
}
@Override
公共afterBodyReadオブジェクト(オブジェクト本体、HttpInputMessage inputMessage、MethodParameterパラメータたtargetTypeタイプ、
クラス<延びHttpMessageConverterタイプ<>> converterType ??){
戻り体;
}
}
上付き文字ConditionalOnPropertyアノテーションは、唯一の条件が真であることを示しそれがオンになっている場合、復号機能、構成は、開放または閉鎖復号化機能とすることができます。実際の復号化ロジックは、暗号に委託、DecryptHttpInputMessageを残しました。
/ **
*
* @author xiongshiyan
* /
publicクラスDecryptHttpInputMessage実装HttpInputMessage {
プライベートHttpInputMessage inputMessage。
プライベート文字列の文字セット。
プライベート暗号暗号。
公共DecryptHttpInputMessage(HttpInputMessage inputMessage、文字列の文字セット、暗号クリプト){
this.inputMessage = inputMessage。
this.charset =文字セット。
this.crypto =暗号。
}
@Override
公共のInputStream getBodyは()のIOException {スロー
文字列のコンテンツを= IoUtil.read(inputMessage.getBody()、文字セット)。
ストリングdecryptBody = crypto.decrypt(コンテンツ、文字セット)。
AれるByteArrayInputStream新しい新しいリターン(decryptBody.getBytes(文字セット));
}
@Override
公共HttpHeaders getHeaders(){
戻りinputMessage.getHeaders();
}
}
暗号化の戻り値を、ResponseBodyAdvice実現EncryptResponseBodyAdviceは、定義されました。
/ **
*要求応答を<BR>基づく処理
*
*データ暗号化操作を添加する方法が行われ@Encrypt
*
発現* @authorクマ詩
*
* /
@ControllerAdvice
@ConditionalOnProperty(接頭辞= "spring.crypto.response.encrypt"を、 =名前)=真matchIfMissingに、 "真の" havingValue =、 "有効"
を実装ResponseBodyAdvice <オブジェクト> {パブリッククラスEncryptResponseBodyAdvice
):@value( "UTF-8} {$ spring.crypto.request.decrypt.charset"
プライベート文字列の文字セット= "UTF-8";
@Autowired
@Qualifier( "rrCrypto")
プライベート暗号暗号;
@Override
?パブリックブールサポート(MethodParameter戻り値の、クラス<HttpMessageConverter種類を拡張<?>> converterType){
trueを返します。
}
@Override
パブリックオブジェクトbeforeBodyWrite(オブジェクト本体、MethodParameter戻り値の、のMediaType selectedContentType、
クラス<延びHttpMessageConverter <>> selectedConverterType、ServerHttpRequest要求、ServerHttpResponse応答?){
ブール暗号= NeedCrypto.needEncrypt(戻り値の)。
(!暗号化)であれば、{
リターン体;
}
(!ResponseMsgのinstanceof(本体))なら、{
戻り体;
}
//只针对ResponseMsg的データ进行加密
ResponseMsg responseMsg =(ResponseMsg)本体;
オブジェクトデータ= responseMsg.getData()。
IF(ヌル==データ){
体を返します。
}
文字列xxを。
<?>クラスデータクラス= data.getClass();
もし{(文字列)のinstanceof dataClass.isPrimitive()||(データ)
XX = String.valueOf(データ)。
}他{
//のJavaBean、マップ、リスト等先序列化
する場合(List.class.isAssignableFrom(データクラス)){
XX = JsonUtil.serializeList((一覧<OBJECT>)データ)。
}そうであれば(Map.class.isAssignableFrom(データクラス)){
XX = JsonUtil.serializeMap((MAP <文字列、オブジェクト>)データ)。
}他{
XX = JsonUtil.serializeJavaBean(データ)。
}
}
responseMsg.setData(crypto.encrypt(XX、文字セット));
戻りresponseMsg;
}
}
真暗号は、暗号化インターフェースである暗号化ロジックに委ね、多くの実装クラスがあり、https://gitee.com/xxssyyyyssxx参照/共通暗号:
/ **
*暗号化と復号化モードの要求と応答システム
* @author xiongshiyan 2018年8月14日AT、[email protected] Meまたは電話番号15208384257と電子メールの連絡先で
* /
@Configuration
パブリッククラスRRCryptoConfig {
/ **
*暗号化同じ方法を使用して復号化
* /
@Bean(「rrCrypto」)
パブリック暗号rrCrypto(){
新新しいAesCrypto(「キーキー」)を返す;
}
}
このように、完全なインターフェイスの暗号化と復号化が実現されているため。
----------------
免責事項:この記事は元の記事CSDNブロガー「ヘンチーヘン李」であり、BY-SAの著作権契約CC 4.0に従って、再現し、元のソースのリンクを添付してくださいそしてこの文。
オリジナルリンクします。https://blog.csdn.net/xxssyyyyssxx/article/details/88219298