前言
新手学习还真是痛苦啊~尝试将jasypt中的秘钥由用户输入
简介
devtool是springboot的热部署工具
jasypt是密码Digest认证,文本和对象加密,集成hibernate,Spring Security(Acegi)来增强密码管理
所用IDE: intellji IDEA
1.创建pom.xml
spring boot框架
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.5.20</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt-spring31</artifactId>
<version>1.9.1</version>
</dependency>
<!--jstl-->
<!--environment-->
<!--other template-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.Controller
package com.controller;
import com.entity.springTest;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@Controller
public class JspController implements EnvironmentPostProcessor {
private Properties prop=new Properties();
private springTest springtest;
private springTest springtest1;
@Value("${app.myUrl}")
private String myUrlGlobal;
@Value("${app.myPassword:defaultvalue}")
private String myPasswordGlobal;
@Value("app.ftpUserName")
private String ftpUserNameGlobal;
@Value("app.ftpPath")
private String ftpPathGlobal;
private StandardPBEStringEncryptor stringEncryptor;
private StandardPBEStringEncryptor stringEncryptor1;
@Autowired
private Environment env;
@Autowired
private ConfigurableEnvironment environment;
@Autowired
private ApplicationContext ctx;
private FileOutputStream fileOutputStream;
private InputStream fileInputStream;
private InputStream targetFileInputStream;
private FileOutputStream targeTFileOutputStream;
private String result;
private String passwordResult;
private String ftpUserNameResult;
private String ftpPathResult;
private PropertySourceLoader loader;
private static String KEY="";
private static String keyValue;
@RequestMapping("/inputCipher")
public ModelAndView inputCipher(String cipher){
//将秘钥存入全局变量
this.KEY=cipher;
try {
//读入资源目录下的application.properties 文件
fileInputStream=new BufferedInputStream(new FileInputStream("./src/main/resources/application.properties"));
prop=new Properties();
prop.load(fileInputStream);
//将properties的值读入到springtest 然后返回页面
springtest=new springTest();
springtest.setMyUrl(prop.getProperty("app.myUrl"));
springtest.setMyPassword(prop.getProperty("app.myPassword"));
springtest.setFtpPath(prop.getProperty("app.ftpPath"));
springtest.setFtpUserName(prop.getProperty("app.ftpUserName"));
springtest.setSignal("already entered");
//将文件关闭
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return new ModelAndView("index","springtest",springtest);
}
//解密action
@RequestMapping("/encrpt")
public ModelAndView encrypt(String Encrpt, String passwordEncrpt, HttpServletRequest request, String ftpUserName, String ftpPath) {
try {
//如果点击的是解密按钮,返回解密输入key值页面
if(request.getParameter("Button").equals("decrypt")){
return new ModelAndView("testKey");
}
if(KEY.isEmpty()&&request.getParameter("Button").equals("encrypt")){
//如果key值为空或者key值是空字符串,返回到输入key值的jsp页面
springtest=new springTest();
springtest.setSignal("Please type into the password");
return new ModelAndView("inputCipherCode","springtest",springtest);
}else{
springtest.setSignal("Already Entered");
}
stringEncryptor=new StandardPBEStringEncryptor();
stringEncryptor.setPassword(KEY);
//读出数据
fileInputStream=new BufferedInputStream( new FileInputStream("./src/main/resources/application.properties"));
prop.load(fileInputStream);
//得到资源目录下的property里面的值
String value=prop.getProperty("app.myUrl");
String passwordValue=prop.getProperty("app.myPassword");
String ftpUserNameValue=prop.getProperty("app.ftpUserName");
String ftpPathValue=prop.getProperty("app.ftpPath");
//判断前台传入值是否为空或为空的字符串,为空则写入applicaiton.properties里面的默认值进行加密
if(!(Encrpt==null)&&!(Encrpt=="")){
value=Encrpt;
}
if(!(passwordEncrpt==null)&&!(passwordEncrpt=="")){
passwordValue=Encrpt;
}
if(!(ftpUserName==null)&&!(ftpUserName=="")){
ftpUserNameValue=ftpUserName;
}
if(!(ftpPath==null)&&!(ftpPath=="")){
ftpPathValue=ftpPath;
}
//加密数据,变量名后缀是result的为加密过后的字符串
result=stringEncryptor.encrypt(value);
passwordResult=stringEncryptor.encrypt(passwordValue);
ftpUserNameResult=stringEncryptor.encrypt(ftpUserNameValue);
ftpPathResult=stringEncryptor.encrypt(ftpPathValue);
fileOutputStream = new FileOutputStream("./src/main/resources/application.properties", false);
//给加密完的数据套入ENC(),方便@value解密
result="ENC("+result+")";
passwordResult="ENC("+passwordResult+")";
ftpUserNameResult="ENC("+ftpUserNameResult+")";
ftpPathResult="ENC("+ftpPathResult+")";
//存入properties的文件中
prop.setProperty("app.myUrl",result);
prop.setProperty("app.myPassword",passwordResult);
prop.setProperty("app.ftpUserName",ftpUserNameResult);
prop.setProperty("app.ftpPath",ftpPathResult);
prop.setProperty("jasypt.encryptor.password",KEY);
//写入properties数据
prop.store(fileOutputStream,"Success");
fileInputStream.close();
fileOutputStream.close();
//改变环境变量中的值
changeStandardEnvironment();
//通过class文件改写properties
changePropertiesInTarget(KEY);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//写入到springtest的这个entity中,通过ModelAndView返回到页面
springtest=new springTest();
springtest.setMyUrl(""+result);
springtest.setMyPassword(""+passwordResult);
springtest.setFtpPath(ftpPathResult);
springtest.setFtpUserName(ftpUserNameResult);
springtest.setSignal("success");
if(!KEY.isEmpty()){
springtest.setSignal("Already Entered");
}
return new ModelAndView("index","springtest",springtest);
}
//输入解析秘钥
@RequestMapping("/decryptKey")
public ModelAndView decryptValue(String decrypt){
this.keyValue=decrypt;
//判断前后输入key值是否一致
if(keyValue.equals(env.getProperty("jasypt.encryptor.password")))
{
//使用StandardPBEStringEncryptor 的算法进行解密
stringEncryptor1=new StandardPBEStringEncryptor();
stringEncryptor1.setPassword(keyValue);
try {
//读入解密信息
fileInputStream=new BufferedInputStream(new FileInputStream("./src/main/resources/application.properties"));
prop=new Properties();
prop.load(fileInputStream);
String myurl=prop.getProperty("app.myUrl");
String mypassword=prop.getProperty("app.myPassword");
String ftpUserName=prop.getProperty("app.ftpUserName");
String ftpPath=prop.getProperty("app.ftpPath");
//进行裁剪
myurl=myurl.substring(4,myurl.length()-1);
mypassword=mypassword.substring(4,mypassword.length()-1);
ftpUserName=ftpUserName.substring(4,ftpUserName.length()-1);
ftpPath=ftpPath.substring(4,ftpPath.length()-1);
//进行解密并放入到springtest中
springtest=new springTest();
springtest.setMyUrl(stringEncryptor1.decrypt(myurl));
springtest.setMyPassword(stringEncryptor1.decrypt(mypassword));
springtest.setFtpUserName(stringEncryptor1.decrypt(ftpUserName));
springtest.setFtpPath(stringEncryptor1.decrypt(ftpPath));
fileInputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else{
//如果前后密码不匹配报错
throw new RuntimeException("The key word must be similar");
}
return new ModelAndView("index","springtest",springtest);
}
@RequestMapping("/")
public ModelAndView all() {
try {
//读取资源目录下的文件,返回到index页面
fileInputStream=new BufferedInputStream(new FileInputStream("./src/main/resources/application.properties"));
prop=new Properties();
prop.load(fileInputStream);
springtest=new springTest();
springtest.setMyUrl(prop.getProperty("app.myUrl"));
springtest.setMyPassword(prop.getProperty("app.myPassword"));
springtest.setFtpUserName(prop.getProperty("app.ftpUserName"));
springtest.setFtpPath(prop.getProperty("app.ftpPath"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return new ModelAndView("index","springtest",springtest);
}
//读写environment和value 标注的值
@GetMapping(path = "/show")
public ModelAndView showValueFromEnvironmentAndValueAnnotation(String decrypt){
String test1;
String test2;
if(!(decrypt.equals(env.getProperty("jasypt.encryptor.password")))){
String name="the key word is not same, please reenter";
return new ModelAndView("decryptKey","name",name);
}
List<springTest> list=new ArrayList<springTest>();
springtest=new springTest();
springtest.setMyUrl("get from value annotation "+myUrlGlobal);
springtest.setMyPassword("get from value annotation "+myPasswordGlobal);
list.add(springtest);
springtest1=new springTest();
test1=env.getProperty("app.myUrl");
springtest1.setMyUrl("get from environment "+test1);
test2=env.getProperty("app.myPassword");
springtest1.setMyPassword("get from environment "+test2);
list.add(springtest1);
return new ModelAndView("show","list",list);
}
//替换environment中的properties文件
@Bean
public String changeStandardEnvironment(){
Properties prop=new Properties();
try {
InputStream fileInputStream=new BufferedInputStream( new FileInputStream("./src/main/resources/application.properties"));
prop.load(fileInputStream);
String value=prop.getProperty("app.myUrl");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
StandardEnvironment env=ctx.getBean(StandardEnvironment.class);
env.getPropertySources().replace("applicationConfig: [classpath:/application.properties]",new PropertiesPropertySource("applicationConfig: [classpath:/application.properties]",prop));
return "newbee";
}
//通过应用getclass的值修改编译目录下的properties文件,未完成,只做了读取
@Bean
public String changePropertiesByClass(){
Properties properties;
properties=new Properties();
Class clazz=JspController.class;
InputStream in=clazz.getResourceAsStream("/application.properties");
try {
properties.load(in);
System.out.println("change properties by class"+properties.getProperty("app.myUrl"));
System.out.println("change properties by class"+properties.getProperty("app.myPassword"));
} catch (IOException e) {
e.printStackTrace();
}
return "Success";
}
//通过重写postProcessEnvironment改变环境变量中的properties值,未完成
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Resource path=new ClassPathResource("./src/main/resources/application.properties");
PropertySource<?> propertySource=loadProperties(path);
environment.getPropertySources().addLast(propertySource);
System.out.println("===================================enter");
}
//返回properties 的值
private PropertySource<?> loadProperties(Resource path){
if (!path.exists()) {
throw new IllegalArgumentException("Resource " + path + " does not exist");
}
try {
return this.loader.load("custom-resource",path).get(0);
}
catch (IOException ex) {
throw new IllegalStateException(
"Failed to load yaml configuration from " + path, ex);
}
}
//通过file的读入读出改变编辑目录下中的properties的值
private Boolean changePropertiesInTarget(String KEY1){
Properties properties=new Properties();
Properties properties1=new Properties();
try {
InputStream inProperties=new BufferedInputStream(new FileInputStream("./src/main/resources/application.properties"));
properties.load(inProperties);
FileOutputStream outproperties=new FileOutputStream("./target/classes/application.properties",false);
properties1.setProperty("app.myUrl",properties.getProperty("app.myUrl"));
properties1.setProperty("app.myPassword",properties.getProperty("app.myPassword"));
properties1.setProperty("spring.mvc.view.suffix",properties.getProperty("spring.mvc.view.suffix"));
properties1.setProperty("app.ftpUserName",properties.getProperty("app.ftpUserName"));
properties1.setProperty("jasypt.encryptor.password",KEY1);
properties1.setProperty("server.port",properties.getProperty("server.port"));
properties1.setProperty("app.ftpPath",properties.getProperty("app.ftpPath"));
properties1.setProperty("server.servlet.context-path",properties.getProperty("server.servlet.context-path"));
properties1.store(outproperties,"prepared");
inProperties.close();
outproperties.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
3.Properties 文件属性
app.myPassword=give
server.servlet.context-path=/ency
app.ftpPath=/pub/here
server.port=7979
spring.mvc.view.prefix=/META-INF/views/
jasypt.encryptor.password=654321
app.ftpUserName=admin
app.myUrl=ftp://192.108.0.1:9090
spring.mvc.view.suffix=.jsp
4.文件目录