第40天:JavaEE应用&SpringBoot框架&JWT身份鉴权&打包部署JAR&WAR

JWT:https://cloud.tencent.com/developer/article/1460770

jwt有三个部分:

1
2
3
头部(header)
载荷(payload)
签证(signature)

jwt解密网站:https://jwt.io/

image-20250807085124169

JwtController.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
package cn.xiaodi.testjwt.demos.web;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
public class JwtController {
//模拟用户的jwt身份创建 数据的jwt加密

@PostMapping("/jwtcreate")
@ResponseBody
public static String main(Integer id,String user,String pass) {
String jwttoken = JWT.create()
//设置创建的header部分
//.withHeader()

//设置创建的payload部分
.withClaim("userid", id)
.withClaim("username", user)
.withClaim("password", pass)
//设置时效(JWT过期时间)
//.withExpiresAt()

//创建设置的signature部分 算法和密匙
.sign(Algorithm.HMAC256("xiaodisec"));

System.out.println(jwttoken);
return jwttoken;
}


//模拟JWT身份的检测 jwt数据解密

@PostMapping("/jwtcheck")
@ResponseBody
public static String jwtcheck(String jwtdata){
//String jwtdata="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6ImExMjM0NTYiLCJ1c2VyaWQiOjEsInVzZXJuYW1lIjoiYWRtaW4ifQ.nkMIxHJKyGAHa3aDtTAy5_9j51yWDTQHEL8n-dqE33w";

//构建解密注册
JWTVerifier jwt = JWT.require(Algorithm.HMAC256("xiaodisec")).build();

//解密注册数据
DecodedJWT verify = jwt.verify(jwtdata);

//提取注册解密数据 payload部分
Integer userid = verify.getClaim("userid").asInt();
String username=verify.getClaim("username").asString();
String password=verify.getClaim("password").asString();

System.out.println(userid+username+password);
return "admin page";


// if(username.equals("admin")){
// return "admin";
// }else {
// return "gay?";
// }


//攻击者要模拟使用xiaodi用户去登录




//提取header部分
//verify.getHeader();
//提取sign签名部分
//verify.getSignature();



}

}

image-20250807103059667

前端界面index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<body>
<h1>hello word!!!</h1>
<p>this is a html page</p>

<form action="../jwtcreate" method="post">
id:<input type="text" name="id"><br>
user:<input type="text" name="user"><br>
pass:<input type="text" name="pass"><br>
<input type="submit" value="create">
</form>

<form action="../jwtcheck" method="post">
jwtdata:<input type="text" name="jwtdata"><br>
<input type="submit" value="check">
</form>

</body>
</html>

jwt的安全性:

1
2
3
4
5
6
7
就算对方可以更改payload这里的值,然后通过jwt.io这个网站生成的值,去替换登陆,这样是不行的,所以这里jwt本身就有一定的鉴权能力,当然最建议的还是代码同时进行鉴权,然后jwt也用上。两种一起就更加安全。

安全问题:
1、none头部,这样的问题会导致密钥失效。等于没有密钥
2、空密钥,这样的问题就可以直接修改payload的部分,进行越权
3、CVE漏洞,这种就是jwt这个协议本身的漏洞
4、如果上面的方式都没有用,那么只有通过爆破jwt密钥的方式了

打包的java的项目jar包&&war包

通过这样的方式上线的项目,一般就没有源码泄漏的风险。就算有泄漏,也需要进行反编译。

安全开发

1
2
安全开发总结:
熟悉了基本代码之后,发现对一个网站业务的功能的了解,才能更好的去挖掘漏洞,比如之前有的在线翻译造成的domxss,还有这个模板注入,都是网站为了功能的方便性,然后造成的安全问题。