浏览代码

扩展core-security,引用jasypt工具,支持配置文件加密,提供通用的加解密服务工具;扩展starter-api,默认依赖core-solar自动判断内置密钥,并提供/api/boot开头的内置接口

Signed-off-by: luoshi <luoshi@qmth.com.cn>
luoshi 1 年之前
父节点
当前提交
e7d4a43004

+ 4 - 0
core-security/pom.xml

@@ -20,6 +20,10 @@
             <groupId>com.qmth.boot</groupId>
             <artifactId>core-models</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.github.ulisesbocchio</groupId>
+            <artifactId>jasypt-spring-boot-starter</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot</artifactId>

+ 29 - 0
core-security/src/main/java/com/qmth/boot/core/security/config/SecurityAutoConfiguration.java

@@ -1,10 +1,39 @@
 package com.qmth.boot.core.security.config;
 
+import com.qmth.boot.core.security.service.EncryptKeyProvider;
+import com.qmth.boot.core.security.service.EncryptService;
+import com.qmth.boot.core.security.service.impl.DefaultEncryptKeyProvider;
+import org.jasypt.encryption.StringEncryptor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 
+import javax.validation.constraints.NotNull;
+
 @Configuration
 @ComponentScan("com.qmth.boot.core.security")
 public class SecurityAutoConfiguration {
 
+    @Bean
+    @ConditionalOnMissingBean(EncryptKeyProvider.class)
+    public EncryptKeyProvider encryptKeyProvider() {
+        return new DefaultEncryptKeyProvider();
+    }
+
+    @Bean("jasyptStringEncryptor")
+    public StringEncryptor stringEncryptor(@NotNull EncryptService encryptService) {
+        return new StringEncryptor() {
+
+            @Override
+            public String encrypt(String s) {
+                return encryptService.encrypt(s);
+            }
+
+            @Override
+            public String decrypt(String s) {
+                return encryptService.decrypt(s);
+            }
+        };
+    }
 }

+ 14 - 0
core-security/src/main/java/com/qmth/boot/core/security/service/EncryptKeyProvider.java

@@ -0,0 +1,14 @@
+package com.qmth.boot.core.security.service;
+
+/**
+ * 加解密密钥提供接口,可以由上层应用自定义实现
+ */
+public interface EncryptKeyProvider {
+
+    /**
+     * 获取密钥字符串
+     *
+     * @return
+     */
+    String getKey();
+}

+ 31 - 0
core-security/src/main/java/com/qmth/boot/core/security/service/EncryptService.java

@@ -0,0 +1,31 @@
+package com.qmth.boot.core.security.service;
+
+/**
+ * 加解密等安全服务接口
+ */
+public interface EncryptService {
+
+    /**
+     * 使用对称算法进行字符串加密
+     *
+     * @param text 明文
+     * @return
+     */
+    String encrypt(String text);
+
+    /**
+     * 使用对称算法进行字符串解密
+     *
+     * @param text 密文
+     * @return
+     */
+    String decrypt(String text);
+
+    /**
+     * 使用散列算法生成密文,通常用于密码等数据的不可逆加密保存
+     *
+     * @param text
+     * @return
+     */
+    String hash(String text);
+}

+ 16 - 0
core-security/src/main/java/com/qmth/boot/core/security/service/impl/DefaultEncryptKeyProvider.java

@@ -0,0 +1,16 @@
+package com.qmth.boot.core.security.service.impl;
+
+import com.qmth.boot.core.security.service.EncryptKeyProvider;
+
+/**
+ * 基础密钥提供服务,使用固定字符串
+ */
+public class DefaultEncryptKeyProvider implements EncryptKeyProvider {
+
+    private static final String DEFAULT_KEY = "qmth";
+
+    @Override
+    public String getKey() {
+        return DEFAULT_KEY;
+    }
+}

+ 41 - 0
core-security/src/main/java/com/qmth/boot/core/security/service/impl/DefaultEncryptService.java

@@ -0,0 +1,41 @@
+package com.qmth.boot.core.security.service.impl;
+
+import com.qmth.boot.core.security.service.EncryptKeyProvider;
+import com.qmth.boot.core.security.service.EncryptService;
+import com.qmth.boot.tools.crypto.AES;
+import com.qmth.boot.tools.models.ByteArray;
+import org.springframework.stereotype.Service;
+
+import javax.validation.constraints.NotNull;
+
+@Service
+public class DefaultEncryptService implements EncryptService {
+
+    private String key, vector;
+
+    public DefaultEncryptService(@NotNull EncryptKeyProvider encryptKeyProvider) {
+        String keyDigest = ByteArray.sha1(ByteArray.fromString(encryptKeyProvider.getKey()).toBase64()).toHexString();
+        this.key = keyDigest.substring(0, 16);
+        this.vector = keyDigest.substring(keyDigest.length() - 16);
+    }
+
+    public String encrypt(String text) {
+        try {
+            return AES.encrypt(ByteArray.fromString(text).value(), key, vector).toHexString().toLowerCase();
+        } catch (Exception e) {
+            throw new RuntimeException("string encrypt error", e);
+        }
+    }
+
+    public String decrypt(String text) {
+        try {
+            return AES.decrypt(ByteArray.fromHexString(text).value(), key, vector).toString();
+        } catch (Exception e) {
+            throw new RuntimeException("string decrypt error", e);
+        }
+    }
+
+    public String hash(String text) {
+        return ByteArray.sha1(ByteArray.sha1(text).toHexString() + key + text.length()).toHexString().toLowerCase();
+    }
+}

+ 26 - 0
core-security/src/test/java/com/qmth/boot/test/core/security/EncryptServiceTest.java

@@ -0,0 +1,26 @@
+package com.qmth.boot.test.core.security;
+
+import com.qmth.boot.core.security.service.EncryptService;
+import com.qmth.boot.core.security.service.impl.DefaultEncryptKeyProvider;
+import com.qmth.boot.core.security.service.impl.DefaultEncryptService;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class EncryptServiceTest {
+
+    private static EncryptService encryptService;
+
+    @BeforeClass
+    public static void prepare() {
+        encryptService = new DefaultEncryptService(new DefaultEncryptKeyProvider());
+    }
+
+    @Test
+    public void test() {
+        String text = RandomStringUtils.random(64, true, true);
+        Assert.assertEquals(text, encryptService.decrypt(encryptService.encrypt(text)));
+        System.out.println(encryptService.encrypt("root"));
+    }
+}

+ 11 - 0
pom.xml

@@ -402,6 +402,17 @@
                 <artifactId>javase</artifactId>
                 <version>${zxing.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.github.ulisesbocchio</groupId>
+                <artifactId>jasypt-spring-boot-starter</artifactId>
+                <version>3.0.5</version>
+            </dependency>
+            <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on -->
+            <dependency>
+                <groupId>org.bouncycastle</groupId>
+                <artifactId>bcprov-jdk18on</artifactId>
+                <version>1.77</version>
+            </dependency>
             <dependency>
                 <groupId>junit</groupId>
                 <artifactId>junit</artifactId>

+ 1 - 1
starter-api/pom.xml

@@ -42,7 +42,7 @@
         </dependency>
         <dependency>
             <groupId>com.qmth.boot</groupId>
-            <artifactId>core-models</artifactId>
+            <artifactId>core-solar</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 16 - 0
starter-api/src/main/java/com/qmth/boot/api/config/ApiAutoConfiguration.java

@@ -1,12 +1,28 @@
 package com.qmth.boot.api.config;
 
+import com.qmth.boot.core.security.service.EncryptKeyProvider;
+import com.qmth.boot.core.security.service.impl.DefaultEncryptKeyProvider;
+import com.qmth.boot.core.solar.config.SolarProperties;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.PropertySource;
 
+import javax.validation.constraints.NotNull;
+
 @Configuration
 @ComponentScan("com.qmth.boot.api")
 @PropertySource("classpath:actuator.properties")
 public class ApiAutoConfiguration {
 
+    @Bean
+    @ConditionalOnBean(SolarProperties.class)
+    public EncryptKeyProvider encryptKeyProvider(@NotNull SolarProperties solarProperties) {
+        return StringUtils.isNotBlank(solarProperties.getAppCode()) ?
+                solarProperties::getAppCode :
+                new DefaultEncryptKeyProvider();
+    }
+
 }

+ 2 - 0
starter-api/src/main/java/com/qmth/boot/api/constant/ApiConstant.java

@@ -6,6 +6,8 @@ public interface ApiConstant {
 
     String DEFAULT_URI_PREFIX = "/api";
 
+    String BOOT_URI_PREFIX = "/boot";
+
     String DEFAULT_ERROR_URI = "/error";
 
     String CONFIG_PREFIX = CoreConstant.CONFIG_PREFIX + ".api";

+ 37 - 0
starter-api/src/main/java/com/qmth/boot/api/controller/BootController.java

@@ -0,0 +1,37 @@
+package com.qmth.boot.api.controller;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.boot.core.solar.config.SolarProperties;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("${" + ApiConstant.CONFIG_PREFIX + ".uri-prefix:" + ApiConstant.DEFAULT_URI_PREFIX + "}"
+        + ApiConstant.BOOT_URI_PREFIX)
+@Aac(auth = false, strict = false)
+
+public class BootController {
+
+    private SolarProperties solarProperties;
+
+    private Map<String, Object> appInfo;
+
+    public BootController(SolarProperties solarProperties) {
+        this.solarProperties = solarProperties;
+        this.appInfo = new HashMap() {{
+            put("app", solarProperties.getAppCode());
+            put("module", solarProperties.getModuleCode());
+            put("version", solarProperties.getAppVersion());
+        }};
+    }
+
+    @RequestMapping("/app-info")
+    public Object appInfo() {
+        return appInfo;
+    }
+
+}