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

时间轴:

演示案例:

SpringBoot-身份鉴权-JWT 技术

SpringBoot-打包部署-JAR&WAR

SpringBoot-身份鉴权-JWT 技术

SpringBoot- 身份鉴权 -JWT 技术
JWT(JSON Web Token) 是由服务端用加密算法对信息签名来保证其完整性和不可伪
造;
Token 里可以包含所有必要信息,这样服务端就无需保存任何关于用户或会话的信息;
JWT 用于身份认证、会话维持等。由三部分组成, header 、 payload 与 signature 。
参考: https://cloud.tencent.com/developer/article/2101634

jwt,cookie,session的详解:

Cookie、Session、JWT的详解_cookie session jwt-CSDN博客

Header、Payload 和 Signature 是 JSON Web Token(JWT)的三个主要组成部分。

Header(头部): JWT 的头部通常包含两部分信息:声明类型(typ)和使用的签名算法(alg)。这些信息以 JSON 格式存在,然后进行 Base64 编码,形成 JWT 的第一个部分。头部用于描述关于该 JWT 的元数据信息。

复制代码
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload(负载): JWT 的负载包含有关 JWT 主题(subject)及其它声明的信息 。与头部一样,负载也是以 JSON 格式存在,然后进行 Base64 编码,形成 JWT 的第二个部分。

复制代码
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Signature(签名): JWT 的签名是由头部、负载以及一个密钥生成的,用于验证 JWT 的真实性和完整性。签名是由指定的签名算法对经过 Base64 编码的头部和负载组合而成的字符串进行签名生成的。

例如,使用 HMAC SHaA-256 算法生成签名:

复制代码
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

最终,JWT 是由这三个部分组成的字符串,形如 **header.payload.signature**。JWT 通常用于在网络上安全地传输信息,例如在身份验证过程中传递令牌。

案例1:

1.创建TestJwt:

2.勾选web组件:

3.放入依赖项:

复制代码
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
4.创建文件JwtController:

4.1创建 JWT
JWT.create()
4.2配置 JWT
JWT.create()
//header
.withHeader(map)
//payload
.withClaim("userid",id)
.withClaim("username",user)
.withClaim("password",pass)
//signature
.sign(Algorithm.HMAC256("xiaodisec"));

java 复制代码
package cn.xiaodou.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 void main(String[] args) {
        String jwttoken = JWT.create()
                //设置创建的header部分
                //.withHeader()

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

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

        System.out.println(jwttoken);
    }
}

测试过程:

若有报错:

java jdk版本过低或者jwt的版本过高导致了不匹配

可以jdk提高到11来进行处理,或者将jwt版本降下来。

jwt分析:

可以进行jwt解密:

JSON Web Tokens - jwt.io

虽然能解密出来。但是你不知道他加密的密钥。从而也无法登录。

5.对jwt进行服务器验证:

4 、解析 JWT
// 构建解密注册
JWTVerifier jwt =
JWT.require(Algorithm.HMAC256("xiaodisec")).build();
// 解密注册数据
DecodedJWT verify = jwt.verify(jwtdata);
// 提取解密数据
Integer userid = verify.getClaim("userid").asInt();

java 复制代码
package cn.xiaodou.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;


@Controller
public class JwtController {
    //模拟用户的jwt身份创建 数据的jwt加密
    public static void main(String[] args) {
        String jwttoken = JWT.create()
                //设置创建的header部分
                //.withHeader()

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

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

        System.out.println(jwttoken);
        jwtcheck(jwttoken);

    }


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

    public static void jwtcheck(String jwtdata) {
        //String jwtdata="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IjEyMzQ1NiIsInVzZXJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiJ9.q__DmCYaffqXmQweBgITek-NmhsSAhgwExNA3lQspQk";

        //构建解密注册
        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);


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


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

运行结果:

6、配置前端提交数据访问客户端页面

在resources→static→index.html创建如下的前端页面

html 复制代码
<html>
<body>
<h1>hello word!!!</h1>
<p>this is a html page</p>
</body>

<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>


</html>

后端改成web界面:

java 复制代码
package cn.xiaodou.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 com.sun.org.apache.xpath.internal.objects.XString;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
public class JwtController {
    @PostMapping("/jwtcreate")
    @ResponseBody
    //模拟用户的jwt身份创建 数据的jwt加密
    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;

    }

    @PostMapping("/jwtcheck")
    @ResponseBody
    //模拟JWT身份的检测 jwt数据解密
    public static String jwtcheck(String jwtdata) {

        //String jwtdata="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IjEyMzQ1NiIsInVzZXJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiJ9.q__DmCYaffqXmQweBgITek-NmhsSAhgwExNA3lQspQk";

        //构建解密注册
        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);

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


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

访问页面进行测试:(输入admin,若解码与admin相同返回正常值,证明登录成功)


7、安全问题

参考: https://cloud.tencent.com/developer/article/2101634

1.如果使用jwt.io直接修改后访问会成功吗?

将admin改为xiaodi

将修改后得到的值放入刚才的页面进行解密:

会发现进行了报错处理。

若在此处加上signature,那就会成功:

总结:

SpringBoot-打包部署-JAR&WAR

参考: https://mp.weixin.qq.com/s/HyqVt7EMFcuKXfiejtfleg
SpringBoot 项目打包在 linux 服务器中运行 :
① jar 类型项目
jar类型项目使用 SpringBoot打包 插件打包时,会在打成的 jar中内置tomcat的jar。
所以使用 jdk直接运行jar即可,jar项目中功能将代码放到其内置的tomcat中运行。

如何进行项目打包呢?

第一种打包方式jar:

1.先点击maven旁白的clean(将运行产生的一些配置进行清空)

2.点击maven旁白的package进行打包。

或使用指令:

maven-clean-package

生成的文件会在此处:

报错解决:用idea生成jar包时没有original文件-CSDN博客
java -jar XXX.jar 没有主清单属性以及找不到或无法加载主类的问题-CSDN博客

运行时使用

复制代码
java -jar TestJwt-0.0.1-SNAPSHOT.jar

若运行的时候进行报错:

通常报错是没有mainclass,或者下面的<skip>跳过了上面的mainclass

改成<skip>false</skip>或者直接删除掉。

正常情况下为:

复制代码
java -jar TestJwt-0.0.1-SNAPSHOT.jar

(重复以上的操作)

第二种打包方式war:

在打包时需要将内置的tomcat插件排除 ,配置servlet的依赖和修改pom.xml,

然后将war文件放到tomcat安装目录webapps下,启动运行tomcat自动解析即可。

1.修改pom.xml:

复制代码
**<packaging>war</packaging>**

2.启动类里面加入配置:

java 复制代码
package cn.xiaodou.testjwt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class TestJwtApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(TestJwtApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(TestJwtApplication.class);
    }
}

3.使用clean,package进行打包。

遇到报错:

java 复制代码
<fail0nMissingWebXml>false</fail0nMissingWebXml>

4、war放置tomcat的后E:\tomcat\apache-tomcat-9.0.74-windows-x64\apache-tomcat-9.0.74\webapps

双击使用tomcat中的bin/start up.bat启动

会发现在webapps中多了一个TestJwt-0.0.1-SNAPSHOT页面:

点击查看其路由路径进行访问:

尝试访问:

源码泄露问题:

访问jar文件,会发现全部都被加密了和原来我们看到的不一样。

从而推出了反编译技术将class转换为java。

访问文件发现不能像以前一样下载源文件。
如何进行反编译呢?

将文件解压后,将路径地址放入

成功反编译出来:

上面显示的是反编译.class文件,字节码版本 52.0(Java8)。

但注释那些。

本文章有李豆豆喵和番薯小羊卷~共同完成。

相关推荐
用户9083246027317 小时前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
用户8307196840822 天前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解2 天前
Spring Boot 视图层与模板引擎
spring boot·后端
Java水解2 天前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
洋洋技术笔记2 天前
Spring Boot Web MVC配置详解
spring boot·后端
初次攀爬者2 天前
Kafka 基础介绍
spring boot·kafka·消息队列
用户8307196840822 天前
spring ai alibaba + nacos +mcp 实现mcp服务负载均衡调用实战
spring boot·spring·mcp
Java水解3 天前
SpringBoot3全栈开发实战:从入门到精通的完整指南
spring boot·后端
初次攀爬者3 天前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺3 天前
搞懂@Autowired 与@Resuorce
java·spring boot·后端