SpringBootインタフェースは、暗号化と復号化のプロセスを統一します

免責事項:この記事は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

公開された51元の記事 ウォン称賛80 ビュー930 000 +

おすすめ

転載: blog.csdn.net/xiyang_1990/article/details/103061419