最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot?Starter自定義全局加解密組件的詳細(xì)流程

 更新時(shí)間:2024年02月06日 11:14:23   作者:xbhog  
SpringBoot?Starter作用將一組相關(guān)的依賴打包,簡化項(xiàng)目的配置和初始化過程,通過特定的Starter開發(fā)者可以快速的實(shí)現(xiàn)特定功能模塊的開發(fā)和擴(kuò)展,本文給大家介紹了SpringBoot?Starter自定義全局加解密組件的詳細(xì)流程,需要的朋友可以參考下

目的

  • 了解SpringBoot Starter相關(guān)概念以及開發(fā)流程
  • 實(shí)現(xiàn)自定義SpringBoot Starter(全局加解密)
  • 了解測試流程
  • 優(yōu)化

最終引用的效果:

<dependency>
    <groupId>com.xbhog</groupId>
    <artifactId>globalValidation-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

了解SpringBoot Starter相關(guān)概念以及開發(fā)流程

SpringBoot Starter

SpringBoot Starter作用將一組相關(guān)的依賴打包,簡化項(xiàng)目的配置和初始化過程,通過特定的Starter開發(fā)者可以快速的實(shí)現(xiàn)特定功能模塊的開發(fā)和擴(kuò)展。

自定義Starter能夠促進(jìn)團(tuán)隊(duì)內(nèi)部資源的復(fù)用,保持項(xiàng)目間的一致性,提升協(xié)作效率并且有助于構(gòu)建穩(wěn)定、高效的大型系統(tǒng)。

開發(fā)流程

注入SpringBoot的方式

在剛開始開發(fā)Starter的時(shí)候,首先考慮的是怎么能注入到SpringBoot中?

這部分涉及到部分SpringBoot的自動(dòng)裝配原理,不太清楚的朋友可以補(bǔ)習(xí)下;

注入SpringBoot需要配置文件,在項(xiàng)目中的resources資源目錄中創(chuàng)建該目錄和文件。

demo-spring-boot-starter
└── src
    └── main
        └── java
            └── com.xbhog
                ├── DemoBean.java
                └── DemoBeanConfig.java
        └── resources
                └── META-INF
                    └── spring.factories

spring.factories中我們指定一下自動(dòng)裝配的配置類,格式如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xbhog.DemoBeanConfig
/**
 * @author xbhog
 * @describe:
 */
@Slf4j
@Configuration
public class DemoBeanConfig {
?
    @Bean
    public DemoBean getDemo() {
        log.info("已經(jīng)觸發(fā)了配置類,正在初始化DemoBean...");
        return new DemoBean();
    }
}
@Slf4j
public class DemoBean {
    public void getDemo(){
      log.info("方法調(diào)用成功");
    }
}

這樣就可以將設(shè)置的包掃描路徑下的相關(guān)操作打包到SpringBoot 中。

SpringBoot主類啟動(dòng)器:初始化的操作,感興趣的朋友可以研究下

完成后,我們可以打包該項(xiàng)目,然后在測試工程紅進(jìn)行Maven的引入、測試。

測試

新建Spring 測試工程,引入依賴:

<dependency>
    <groupId>com.xbhog</groupId>
    <artifactId>demo-spring-boot-starter</artifactId>
    <version>1.0</version>
</dependency>
?
@RestController
public class BasicController implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    
    /**兩種引入方式都可以
    @Autowired
    private DemoBean demoBean;*/
?
    @GetMapping("/configTest")
    public void configTest() {
        DemoBean demoBean = applicationContext.getBean(DemoBean.class);
        demoBean.getDemo();
    }
?
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
?

請(qǐng)求地址后,可以觀察控制臺(tái),如下日志表示SpringBoot Starter可以使用了。

到此,一個(gè)簡單的Starter開發(fā)完成了,后續(xù)可以圍繞工程,根據(jù)需求和業(yè)務(wù),對(duì)通用功能(接口操作日志、異常、加解密、白名單等)進(jìn)行封裝,最后打到Maven倉庫中進(jìn)行使用。

自定義SpringBoot Starter(全局加解密)

來源

在之前金融系統(tǒng)開發(fā)中,需要對(duì)接多個(gè)第三方的服務(wù)且數(shù)據(jù)安全性要求比較高;在接口評(píng)審階段需要雙方在數(shù)據(jù)傳輸?shù)臅r(shí)候進(jìn)行接口加解密;起初在第一個(gè)服務(wù)對(duì)接的時(shí)候,將相關(guān)的加解密操作寫到工具類中;隨著后續(xù)服務(wù)的增多,代碼的侵入越來越嚴(yán)重。

封裝

選擇通過Starter進(jìn)行功能的封裝;好處:引用方便,開發(fā)迭代方便,團(tuán)隊(duì)復(fù)用度高且對(duì)業(yè)務(wù)沒有侵入。

開發(fā)

思路:通過配置文件初始化,讓配置類注解@ComponentScan掃描到的Bean等注入到SpringBoot中,通過自定義注解和`RequestBodyAdvice/ResponseBodyAdvice組合攔截請(qǐng)求,在BeforBodyRead/beforeBodyWrite中進(jìn)行數(shù)據(jù)的前置處理,加密或解密后映射到接口接收的字段或?qū)ο蟆?/p>

接口上的操作有兩種方式:

  • 注解+AOP實(shí)現(xiàn)
  • 注解+RequestBodyAdvice/ResponseBodyAdvice

這里我選擇的第二種的RequestBodyAdvice/ResponseBodyAdvice,拋磚引玉一下。

【注】 第二種存在的局限性是:只能針對(duì)POST請(qǐng)求中的Body數(shù)據(jù)處理,無法針對(duì)GET請(qǐng)求進(jìn)行處理。

項(xiàng)目結(jié)構(gòu):

核心代碼:

@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
    log.info("進(jìn)入【RequestBodyDecryptAdvice】beforeBodyRead的操作,方法:{}",parameter.getMethod());
    SecuritySupport securitySupport = parameter.getMethodAnnotation(SecuritySupport.class);
    assert securitySupport != null;
    ContextHolder.setCryptHolder(securitySupport.securityHandler());
    String original = IOUtils.toString(inputMessage.getBody(), Charset.defaultCharset());
    //todo
    log.info("該流水已插入當(dāng)前請(qǐng)求流水表");
    String handler = securitySupport.securityHandler();
    String plainText = original;
    if(StringUtils.isNotBlank(handler)){
        SecurityHandler securityHandler = SpringContextHolder.getBean(handler, SecurityHandler.class);
        plainText = securityHandler.decrypt(original);
    }
    return new MappingJacksonInputMessage(IOUtils.toInputStream(plainText, Charset.defaultCharset()), inputMessage.getHeaders());
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    log.info("進(jìn)入【ResponseBodyEncryptAdvice】beforeBodyWrite的操作,方法:{}",returnType.getMethod());
    String cryptHandler = ContextHolder.getCryptHandler();
    SecurityHandler securityHandler = SpringContextHolder.getBean(cryptHandler, SecurityHandler.class);
    assert body != null;
    return securityHandler.encrypt(body.toString());
}

Starter中的全局加解密默認(rèn)采用的國密非對(duì)稱加密SM2,在開發(fā)過程中遇到了該問題InvalidCipherTextException: invalid cipher text

【原因】 私鑰和公鑰值不是成對(duì)存在的,每次調(diào)用SmUtil.sm2()會(huì)生成不同的隨機(jī)密鑰對(duì)。

【解決】在該Starter中采用@PostConstruct修飾方法,在項(xiàng)目運(yùn)行中只會(huì)初始化運(yùn)行一次該方法,保證了SmUtil.sm2()只會(huì)調(diào)用一次,不會(huì)生成不同的隨機(jī)秘鑰對(duì)。

ISSUES#1890】詳細(xì)請(qǐng)看該地址:https://hub.fgit.cf/dromara/hutool/issues/1890

/**
 * @author xbhog
 * @date 2024/02/01 13:23
 **/
@Slf4j
@Component
public class EncryAdecryHolder {
    public static SM2 sm2 = null;
    @PostConstruct
    public void encryHolder(){
        KeyPair pair = SecureUtil.generateKeyPair("SM2");
        byte[] privateKey = pair.getPrivate().getEncoded();
        byte[] publicKey = pair.getPublic().getEncoded();
        log.info("生成的公鑰:{}",publicKey);
        log.info("生成的私鑰:{}",privateKey);
        sm2= SmUtil.sm2(privateKey, publicKey);
    }
}

除了默認(rèn)的加密方式,還可以通過SecurityHandler接口進(jìn)行擴(kuò)展,擴(kuò)展出來的impl可以在@SecuritySupport(securityHandler="xxxxx")中指定。

/**
 * @author xbhog
 * @describe: 全局加解密注解
 * @date 2023/6/8
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SecuritySupport {
    /*securityHandlerImpl*/
    String securityHandler() default "securityHandlerImpl";
?
    String exceptionResponse() default "";
?
}

測試

復(fù)用之前的測試項(xiàng)目,引用打包的mavne依賴:

<dependency>
    <groupId>com.xbhog</groupId>
    <artifactId>encryAdecry-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

啟動(dòng)項(xiàng)目,初始化公私鑰。

測試接口代碼如下:

@Slf4j
@RestController
public class BasicController implements ApplicationContextAware {
    @Resource(name = "demoSecurityHandlerImpl")
    private SecurityHandler encryAdecry;
    private ApplicationContext applicationContext;
?
    // http://127.0.0.1:8080/hello?name=lisi
    //@SecuritySupport(securityHandler = "demoSecurityHandlerImpl")
    @SecuritySupport
    @PostMapping("/hello")
    public String hello(@RequestBody String name) {
        return "Hello " + name;
    }
?
    @GetMapping("/configTest")
    public String configTest(@RequestParam("name") String name) {
        /*DemoBean demoBean = applicationContext.getBean(DemoBean.class);
        demoBean.getDemo();*/
        return encryAdecry.encrypt(name);
        //return MD5.create().digestHex16(name);
    }
}

優(yōu)化

優(yōu)化后的項(xiàng)目結(jié)構(gòu):

encryAdecry-spring-boot-starter
└── src
    └── main
        └── java
            └── com.xbhog
                ├── advice
                │   ├──ResponseBodyEncryptAdvice.java
                │   └──RequestBodyDecryptAdvice.java
                ├── annotation
                │   └──SecuritySupport
                ├── handler
                │    ├──impl
                │    │   └──EncryAdecryImpl.java
                │    └──SecurityHandler
                └── holder
                │    ├──ContextHolder.java
                │    └──SpringContextHolder.java
                ├──GlobalProperties.java
                └──GlobalConfig.java
        └── resources
                └── META-INF
                    └── spring.factories

增加配置類,用于綁定外部配置(propertiesYAML)到Java對(duì)象的的一種機(jī)制;

@Data
@ConfigurationProperties(GlobalProperties.PREFIX)
public class GlobalProperties {
    /**
     * 默認(rèn)前綴
     */
    public static final String PREFIX = "encryption.type";
    /**
     * 加解密算法
     */
    private String algorithmType;
?
    /**
     * 加解密key值
     */
    private String key;
}

注解修改:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SecuritySupport {
    /**
     * 項(xiàng)目默認(rèn)加解密實(shí)現(xiàn)類encryAdecryImpl
     * */
    String securityHandler() default "encryAdecryImpl";
?
}

重寫Starter默認(rèn)的加解密方式:

?
@Slf4j
@Component
public class EncryAdecryImpl implements SecurityHandler {
?
    @Resource
    private GlobalProperties globalProperties;
    private static volatile SM2 sm2;
?
    @Override
    public String encrypt(String original) {
        log.info("【starter】具體加密的數(shù)據(jù){}",original);
        return sm2.encryptBase64(original, KeyType.PublicKey);
    }
?
    @Override
    public String decrypt(String original) {
        String decryptData = StrUtil.utf8Str(sm2.decryptStr(original, KeyType.PrivateKey));
        log.info("【starter】具體解密的數(shù)據(jù):{}",decryptData);
        return decryptData;
    }
?
    @PostConstruct
    @Override
    public void init() {
        log.info("======>獲取映射的加密算法類型:{}",globalProperties.getAlgorithmType());
        //傳的是加密算法
        KeyPair pair = SecureUtil.generateKeyPair(globalProperties.getAlgorithmType());
        byte[] privateKey = pair.getPrivate().getEncoded();
        byte[] publicKey = pair.getPublic().getEncoded();
        sm2= SmUtil.sm2(privateKey, publicKey);
    }
}

以上就是SpringBoot Starter自定義全局加解密組件的詳細(xì)流程的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Starter加解密組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring+SpringMVC+MyBatis整合詳細(xì)教程(SSM)

    Spring+SpringMVC+MyBatis整合詳細(xì)教程(SSM)

    Spring是一個(gè)開源框架,Spring是于2003 年興起的一個(gè)輕量級(jí)的Java 開發(fā)框架。這篇文章主要介紹了Spring+SpringMVC+MyBatis整合詳細(xì)教程(SSM),需要的朋友可以參考下
    2017-10-10
  • Java?SpringTask定時(shí)自動(dòng)化處理方法

    Java?SpringTask定時(shí)自動(dòng)化處理方法

    這篇文章主要介紹了Java?SpringTask定時(shí)自動(dòng)化處理,通過自動(dòng)化,不僅可以提高工作效率和準(zhǔn)確性,還可以釋放人力資源以專注于更高價(jià)值的工作,需要的朋友可以參考下
    2024-08-08
  • Java在PDF中添加表格過程詳解

    Java在PDF中添加表格過程詳解

    這篇文章主要介紹了Java在PDF中添加表格過程詳解,本文將介紹通過Java編程在PDF文檔中添加表格的方法。添加表格時(shí),可設(shè)置表格邊框、單元格對(duì)齊方式、單元格背景色、單元格合并、插入圖片、設(shè)置行高、列寬、字體、字號(hào)等,需要的朋友可以參考下
    2019-07-07
  • Spring Boot 安全 API 構(gòu)建之加密解密功能的實(shí)踐記錄

    Spring Boot 安全 API 構(gòu)建之加密解密功能的實(shí)踐記錄

    本文詳述了如何在SpringBoot3.3環(huán)境中實(shí)施API加密的最佳實(shí)踐,包括選擇合適的加密算法,密鑰管理,數(shù)據(jù)加密,防止加密漏洞,安全日志記錄,測試和監(jiān)控等方面,同時(shí),文章也對(duì)RSA非對(duì)稱加密和AES對(duì)稱加密的實(shí)現(xiàn)步驟進(jìn)行了詳細(xì)的解析
    2024-10-10
  • spring聲明式事務(wù)管理解析

    spring聲明式事務(wù)管理解析

    這篇文章主要為大家詳細(xì)介紹了spring聲明式事務(wù)管理,對(duì)spring事務(wù)管理進(jìn)行深入了解,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java使用文本塊(Text Blocks)處理多行字符串的操作方法

    Java使用文本塊(Text Blocks)處理多行字符串的操作方法

    本文介紹了Java文本塊(TextBlocks)語法,它簡化多行字符串的處理,保留文本格式、減少錯(cuò)誤、提升代碼可讀性,本文詳細(xì)解釋了文本塊的語法、縮進(jìn)規(guī)則、常用轉(zhuǎn)義符及常見使用場景,同時(shí)注意事項(xiàng),需要的朋友可以參考下
    2026-05-05
  • Java 方法遞歸的思路詳解

    Java 方法遞歸的思路詳解

    程序調(diào)用自身的編程技巧稱為遞歸( recursion)。遞歸做為一種算法在程序設(shè)計(jì)語言中廣泛應(yīng)用。但是如果沒終止條件會(huì)造成死循環(huán),所以遞歸代碼里要有結(jié)束自調(diào)自的條件,接下來講解一下學(xué)習(xí)遞歸的思路
    2022-04-04
  • JAVA IO和NIO的主要區(qū)別及使用說明

    JAVA IO和NIO的主要區(qū)別及使用說明

    Java IO(BIO)阻塞式,逐字節(jié)流處理;NIO非阻塞,基于緩沖區(qū)和通道實(shí)現(xiàn)多路復(fù)用,單線程管理多連接,適合高并發(fā)網(wǎng)絡(luò)編程,IO代碼簡單但性能低,NIO性能高但復(fù)雜度增加,選擇需權(quán)衡開發(fā)效率與性能需求
    2025-09-09
  • 每日六道java新手入門面試題,通往自由的道路--多線程

    每日六道java新手入門面試題,通往自由的道路--多線程

    這篇文章主要為大家分享了最有價(jià)值的6道多線程面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,對(duì)hashCode方法的設(shè)計(jì)、垃圾收集的堆和代進(jìn)行剖析,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 詳解Spring-Boot中如何使用多線程處理任務(wù)

    詳解Spring-Boot中如何使用多線程處理任務(wù)

    本篇文章主要介紹了詳解Spring-Boot中如何使用多線程處理任務(wù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03

最新評(píng)論

罗山县| 贵阳市| 彰化县| 新竹市| 东乌珠穆沁旗| 九台市| 哈密市| 富顺县| 巴马| 额敏县| 长泰县| 通州市| 嵊州市| 宜兴市| 萨迦县| 综艺| 屯留县| 陆丰市| 九龙城区| 大姚县| 来安县| 阆中市| 宜丰县| 营口市| 隆回县| 望谟县| 宕昌县| 韩城市| 鄢陵县| 施秉县| 浑源县| 喀喇沁旗| 广饶县| 翁源县| 九江市| 集贤县| 玉门市| 中牟县| 灵宝市| 额济纳旗| 阆中市|