第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)。

但注释那些。

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

相关推荐
LUCIAZZZ4 小时前
Java中的设计模式违反了哪些设计原则
java·开发语言·spring boot·后端·spring·设计模式
WeiLai11124 小时前
面试基础--Spring Boot启动流程及源码实现
java·spring boot·分布式·后端·面试·架构
m0_548503035 小时前
使用Kubernetes部署Spring Boot项目
spring boot·容器·kubernetes
计算机-秋大田8 小时前
基于Spring Boot的乐乐农产品销售系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
Jing_saveSlave8 小时前
基于 Spring Boot 的企业级快速启动模板 —— spring-quick
spring boot·后端·spring·springboot·敏捷开发·脚手架·企业级
AskHarries8 小时前
Spring Boot如何利用Twilio Verify 发送验证码短信?
java·spring boot·后端
sugar_cookie8 小时前
Spring Boot集成Minio笔记
spring boot·笔记·后端
B站计算机毕业设计超人9 小时前
计算机毕业设计SpringBoot+Vue.js公寓报修管理系统(源码+文档+PPT+讲解)
java·vue.js·spring boot·后端·毕业设计·课程设计·毕设
B站计算机毕业设计超人9 小时前
计算机毕业设计SpringBoot+Vue.js社区养老服务平台(源码+文档+PPT+讲解)
java·vue.js·spring boot·后端·毕业设计·课程设计·毕设