War包二次开发技巧

War包二次开发技巧

概述

近期拿到一个war包项目,里面没有认证功能,也没有源码。对于系统安全来说,直接能访问里面的数据,并对数据操作,是相当不安全的。所以想在项目里面增加一个简单的Basic认证功能,并且使用idea工具能够快速热部署开发。

Tomcat模式

使用Tomcat来进行Basic认证控制新增config/tomcat-users.xml内容

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>

<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<role rolename="test"/>
<user username="root" password="000000" roles="test" />
</tomcat-users>

修改war中的web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<security-constraint>
<web-resource-collection>
<web-resource-name>protected Resource</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>test</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Default</realm-name>
</login-config>

这样就简单实现war项目新增Basic认证了

拦截器模式

目录结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
report
|- out # tomcat编译运行目录
| |- artifacts
| |- xx
| |- xx_war_exploded
|- src # 二次开发目录
| |- main
| |- java
| |- com.xx.xx.safe.filter
| |- HttpAuthBasicFilter.java
| |- resources
| |- http-auth-basic.properties
|- target # 二次开发编译目录
|- tomcat
| |- webapps # 源码目录
| |- WEB-INF
| |- web.xml # 启动配置
|- pom.xml # 二次开发pom
代码调整

HttpAuthBasicFilter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
public class HttpAuthBasicFilter implements Filter {

private static final String SECURITY_BASIC = "BASIC";
private Properties properties;

public void init(FilterConfig filterConfig) throws ServletException {
InputStream in = HttpAuthBasicFilter.class.getClassLoader().getResourceAsStream("http-auth-basic.properties");
properties = new Properties();

try {
properties.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;

String sessionAuth = (String) req.getSession().getAttribute("auth");

if (!Strings.isNullOrEmpty(sessionAuth)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}

if(!checkHeaderAuth(req)) {
resp.setStatus(401);
resp.setHeader("Cache-Control", "no-store");
resp.setDateHeader("Expires", 0);
resp.setHeader("WWW-authenticate", "Basic Realm=\"test\"");
return;
}

req.getSession().setAttribute("auth", "true");
filterChain.doFilter(servletRequest, servletResponse);
}

public void destroy() { }

/**
* 验证Http Header 中的Authorization是否正确
* @param request HttpServletRequest
* @return boolean
* @throws IOException
*/
private boolean checkHeaderAuth(HttpServletRequest request) throws IOException {
String auth = request.getHeader("Authorization");

if (Strings.isNullOrEmpty(auth)) {
return false;
}

if (!auth.toUpperCase().startsWith(SECURITY_BASIC)) {
return false;
}

String decodeVal = getFromBASE64(auth.substring(6));

String authBasicFormat = String.format("%s:%s"
, properties.getProperty("BASIC_ACCOUNT")
, properties.getProperty("BASIC_PASS"));

if (!decodeVal.startsWith(authBasicFormat)) {
return false;
}

return true;
}

/**
* 解析Authorization中的值
* @param s Authorization
* @return Decode Authorization
* @throws IOException
*/
private String getFromBASE64(String s) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
byte[] b = decoder.decodeBuffer(s);
return new String(b);
}

}

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<dependencies>

<dependency>
<groupId>org.eclipse.jetty.orbit</groupId>
<artifactId>javax.servlet</artifactId>
<version>3.0.0.v201112011016</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0.1-jre</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<outputDirectory>
tomcat/webapps/WEB-INF/lib/
</outputDirectory>
</configuration>
</plugin>
<!-- 内置打包法 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

web.xml

1
2
3
4
5
6
7
8
<filter>
<filter-name>HttpAuthBasicFilter</filter-name>
<filter-class>com.xxx.xx.safe.filter.HttpAuthBasicFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpAuthBasicFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
IDEA设置

现在代码都准备差不多了,我们开始准备idea的一些配置

1、首先将webapps中的lib包加入到你的项目中

2、配置Artifacts

3、配置tomcat和deployment

现在大功告成了,下面进行启动

  • 首先启动tomcat为调试模式,因为我们要使用热部署,都懂
  • 在你的二开工程中,进行package就可以打包到tomcat中进行自动依赖了