亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

密碼加密與微服務鑒權java JWT使用方法是什么

發布時間:2021-11-17 13:53:18 來源:億速云 閱讀:118 作者:iii 欄目:大數據

這篇文章主要講解了“密碼加密與微服務鑒權java JWT使用方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“密碼加密與微服務鑒權java JWT使用方法是什么”吧!

1.1、了解微服務狀態

微服務集群中的每個服務,對外提供的都是Rest風格的接口,而Rest風格的一個最重要的規范就是:服務的無狀態性。

什么是無狀態?

1.服務端不保存任何客戶端請求者信息

2.客戶端的每次請求必須自備描述信息,通過這些信息識別客戶端身份

無狀態,在微服務開放中,優勢是?

1.客戶端請求不依賴服務端的信息,任何多次請求不需要必須訪問到同一臺服務

2.服務端的是否集群對客戶端透明

3.服務端可以任意的遷移和伸縮

4.減小服務端儲存壓力

1.2、無狀態登錄實現原理

密碼加密與微服務鑒權java JWT使用方法是什么

  • 服務器端生產唯一標識(注意:最終需要進行校驗)

    • 方案1:UUID,數據單一,不能包含種類過多的信息。

    • 方案2:RSA加密,數據多樣,需要使用算法,有一定的理解難度。【使用】

  • 瀏覽器儲存和自動攜帶數據

    • 方案1:使用cookie,有很多局限性(大小,個數)

    • 方案2:請求參數,get請求URL有長度限制,每一個路徑都需要處理比較麻煩。

    • 方案3:瀏覽器localStroage存儲,請求頭攜帶。【使用】

密碼加密與微服務鑒權java JWT使用方法是什么

2.1、RSA工具

服務與服務之間共享數據,采用JWT先生成數據,在另一個服務中解析數據,為了保證數據安全性,使用RSA對數據進行加密。

使用RSA加密保證token數據在傳輸過程中不會被篡改

  • RSA:非對稱加密算法

    • 同時生產一對密鑰:公鑰和私鑰

    • 公鑰秘鑰:用于加密

    • 私鑰秘鑰:用于解密

    • 特點

工具類RasUtils

package com.czxy.utils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
 * @author 庭前云落
 * @Date 2019/12/13 22:01
 * @description
 */
public class RasUtils {

    /**
     * 從文件中讀取公鑰
     *
     * @param filename 公鑰保存路徑,相對于classpath
     * @return 公鑰對象
     * @throws Exception
     */
    public static PublicKey getPublicKey(String filename) throws Exception {
        byte[] bytes = readFile(filename);
        return getPublicKey(bytes);
    }

    /**
     * 從文件中讀取密鑰
     *
     * @param filename 私鑰保存路徑,相對于classpath
     * @return 私鑰對象
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String filename) throws Exception {
        byte[] bytes = readFile(filename);
        return getPrivateKey(bytes);
    }

    /**
     * 獲取公鑰
     *
     * @param bytes 公鑰的字節形式
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(byte[] bytes) throws Exception {
        X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);
        KeyFactory factory = KeyFactory.getInstance("RSA");
        return factory.generatePublic(spec);
    }

    /**
     * 獲取密鑰
     *
     * @param bytes 私鑰的字節形式
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(byte[] bytes) throws Exception {
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory factory = KeyFactory.getInstance("RSA");
        return factory.generatePrivate(spec);
    }

    /**
     * 根據密文,生存rsa公鑰和私鑰,并寫入指定文件
     *
     * @param publicKeyFilename  公鑰文件路徑
     * @param privateKeyFilename 私鑰文件路徑
     * @param secret             生成密鑰的密文
     * @throws Exception
     */
    public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret) throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        SecureRandom secureRandom = new SecureRandom(secret.getBytes());
        keyPairGenerator.initialize(1024, secureRandom);
        KeyPair keyPair = keyPairGenerator.genKeyPair();
        // 獲取公鑰并寫出
        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        writeFile(publicKeyFilename, publicKeyBytes);
        // 獲取私鑰并寫出
        byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
        writeFile(privateKeyFilename, privateKeyBytes);
    }

    private static byte[] readFile(String fileName) throws Exception {
        return Files.readAllBytes(new File(fileName).toPath());
    }

    private static void writeFile(String destPath, byte[] bytes) throws IOException {
        File dest = new File(destPath);

        //創建父文件夾
        if(!dest.getParentFile().exists()){
            dest.getParentFile().mkdirs();
        }
        //創建需要的文件
        if (!dest.exists()) {
            dest.createNewFile();
        }

        Files.write(dest.toPath(), bytes);
    }
}

2.1.1使用工具

//生成公鑰和私鑰
RasUtils.generateKey(公鑰位置,私鑰位置,密碼);
RasUtils.generateKey(pubKeyPath,priKeyPath,"234");
//獲得公鑰
RasUtils.getPublicKey(pubKeyPath);
//獲得私鑰
RasUtils.getPrivateKey(priKeyPath);
package com.czxy;

import com.czxy.utils.RasUtils;
import org.junit.Test;

import java.security.PrivateKey;
import java.security.PublicKey;

/**
 * @author 庭前云落
 * @Date 2019/12/13 22:07
 * @description
 */
public class TestRAS {

    private static final String pugbKeyPath="D:\\ras\\ras.pub";

    private static final String priKeyPath="D:\\ras\\ras.pri";

    @Test
    public void testRas() throws Exception {
        //生產公鑰和私鑰
        RasUtils.generateKey(pugbKeyPath,priKeyPath,"234");
    }

    @Test
    public void testGetRas() throws Exception {
        //獲得公鑰和私鑰
        PublicKey publicKey = RasUtils.getPublicKey(pugbKeyPath);
        PrivateKey privateKey = RasUtils.getPrivateKey(priKeyPath);
        System.out.println(publicKey.toString());
        System.out.println(privateKey.toString());

    }
}

密碼加密與微服務鑒權java JWT使用方法是什么

3、JWT工具

3.1概述

JWT,全稱是JSON Web Token,是JSON風格輕量級的授權和身份認證規范,可實現無狀態、分布式的Web應用授權:官網:https://jwt.io

  • JWT基于JSON的認證規范。(Json Web Token)

  • 使用JWT目的:生成數據、解析數據

3.2、使用JWT

pom

    <properties>
        <jwt.jjwt.version>0.9.0</jwt.jjwt.version>
        <jwt.joda.version>2.9.7</jwt.joda.version>
        <lombok.version>1.16.20</lombok.version>
        <beanutils.version>1.9.3</beanutils.version>
    </properties>


    <dependencies>
        <!--網關依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <!--添加eureka客戶端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--測試-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--jwt依賴-->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>${beanutils.version}</version>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jwt.jjwt.version}</version>
        </dependency>

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>${jwt.joda.version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>


    </dependencies>

導入工具類

工具類:JwtUtils

package com.czxy.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.beanutils.BeanUtils;
import org.joda.time.DateTime;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.security.PrivateKey;
import java.security.PublicKey;

/**
 * @author 庭前云落
 * @Date 2019/12/13 22:01
 * @description
 */
public class JwtUtils {
    /**
     *  私鑰加密token
     * @param data 需要加密的數據(載荷內容)
     * @param expireMinutes 過期時間,單位:分鐘
     * @param privateKey 私鑰
     * @return
     */
    public static String generateToken(Object data, int expireMinutes, PrivateKey privateKey) throws Exception {
        //1 獲得jwt構建對象
        JwtBuilder jwtBuilder = Jwts.builder();
        //2 設置數據
        if( data == null ) {
            throw new RuntimeException("數據不能為空");
        }
        BeanInfo beanInfo = Introspector.getBeanInfo(data.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            // 獲得屬性名
            String name = propertyDescriptor.getName();
            // 獲得屬性值
            Object value = propertyDescriptor.getReadMethod().invoke(data);
            if(value != null) {
                jwtBuilder.claim(name,value);
            }
        }
        //3 設置過期時間
        jwtBuilder.setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate());
        //4 設置加密
        jwtBuilder.signWith(SignatureAlgorithm.RS256, privateKey);
        //5 構建
        return jwtBuilder.compact();
    }

    /**
     * 通過公鑰解析token
     * @param token 需要解析的數據
     * @param publicKey 公鑰
     * @param beanClass 封裝的JavaBean
     * @return
     * @throws Exception
     */
    public static <T> T  getObjectFromToken(String token, PublicKey publicKey,Class<T> beanClass) throws Exception {
        //1 獲得解析后內容
        Claims body = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token).getBody();
        //2 將內容封裝到對象JavaBean
        T bean = beanClass.newInstance();
        BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            // 獲得屬性名
            String name = propertyDescriptor.getName();
            // 通過屬性名,獲得對應解析的數據
            Object value = body.get(name);
            if(value != null) {
                // 將獲得的數據封裝到對應的JavaBean中
                BeanUtils.setProperty(bean,name,value);
            }
        }
        return bean;
    }
}

時間處理工具:DateTime

//當前時間
DateTime.now().toDate().toLocaleString()
//當前時間加5分鐘
DateTime.now().plusMinutes(5).toDate().toLocaleString()
//當前時間減5分鐘
DateTime.now().minusMinutes(5).toDate().toLocaleString()

3.3、測試

//生成數據, UserInfo --> String(加密)
//JwtUtils.generateToken(數據,過期時間(分鐘), 私鑰)
String token = JwtUtils.generateToken(userInfo,30, RasUtils.getPrivateKey(priKeyPath));

//解析數據, String(加密) --> UserInfo
// JwtUtils.getObjectFromToken(加密數據, 公鑰, 封裝對象.class);
UserInfo userInfo = JwtUtils.getObjectFromToken(token, RasUtils.getPublicKey(pubKeyPath), UserInfo.class);
  • 生產Token

package com.czxy;

import com.czxy.utils.RasUtils;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import org.junit.Test;

/**
 * @author 庭前云落
 * @Date 2019/12/13 22:32
 * @description
 */
public class TestJWT {

    private static final String pugbKeyPath="D:\\ras\\ras.pub";

    private static final String priKeyPath="D:\\ras\\ras.pri";

    @Test
    public void testGenerateToken() throws Exception {
        String str = Jwts.builder()
                .claim("test","庭前云落")
                .setExpiration(DateTime.now().plusMinutes(60).toDate())
                .signWith(SignatureAlgorithm.RS256, RasUtils.getPrivateKey(priKeyPath))
                .compact();
        System.out.println(str);
    }
}
"庭前云落":Token ---》eyJhbGciOiJSUzI1NiJ9.eyJ0ZXN0Ijoi5bqt5YmN5LqR6JC9IiwiZXhwIjoxNTc2MjkzMTEyfQ.a32GamgbG6F1xC-4NtEJNNLX8mcV6Ycyc2bf7_7wX6_xa4LzimqO5ZH9d4bSii-IixYudSreurJ2Rjq72aXvv3nv_VsZasmODeLkBMLtBGhKDztKW3hNQM7rcRLIxL4PFP48xjosJl48F-hXSgEWqYXuC6Voexlk8W4eonRcGqg

密碼加密與微服務鑒權java JWT使用方法是什么

密碼加密與微服務鑒權java JWT使用方法是什么

  • 解析Token

    @Test
    public void testParseToken() throws Exception {
String token="\n" +
        "eyJhbGciOiJSUzI1NiJ9.eyJ0ZXN0Ijoi5bqt5YmN5LqR6JC9IiwiZXhwIjoxNTc2MjkzMTEyfQ.a32GamgbG6F1xC-4NtEJNNLX8mcV6Ycyc2bf7_7wX6_xa4LzimqO5ZH9d4bSii-IixYudSreurJ2Rjq72aXvv3nv_VsZasmODeLkBMLtBGhKDztKW3hNQM7rcRLIxL4PFP48xjosJl48F-hXSgEWqYXuC6Voexlk8W4eonRcGqg";
        Claims claims = Jwts.parser().setSigningKey(RasUtils.getPublicKey(pubKeyPath)).
                parseClaimsJws(token).getBody();
        String text = claims.get("test",String.class);
        System.out.println(text);
    }

密碼加密與微服務鑒權java JWT使用方法是什么

4、生產token和校驗token

編寫測試對象UserInfo

package com.czxy.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author 庭前云落
 * @Date 2019/12/13 21:55
 * @description
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
     private Long id;
     private String username;
}

測試

package com.czxy;

import com.czxy.domain.UserInfo;
import com.czxy.utils.JwtUtils;
import com.czxy.utils.RasUtils;
import org.junit.Test;

/**
 * @author 庭前云落
 * @Date 2019/12/13 22:32
 * @description
 */
public class TestJWT {

    private static final String pubKeyPath="D:\\ras\\ras.pub";

    private static final String priKeyPath="D:\\ras\\ras.pri";

   
    @Test
    public void testToken() throws Exception {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(10L);
        userInfo.setUsername("庭前云落");
        String token = JwtUtils.generateToken(userInfo, 30, RasUtils.getPrivateKey(priKeyPath));
        System.out.println(token);
    }


    @Test
    public void testParserToken() throws Exception {
        String token="eyJhbGciOiJSUzI1NiJ9.eyJjbGFzcyI6ImNvbS5jenh6LmRvbWFpbi5Vc2VySW5mbyIsImlkIjoxMCwidXNlcm5hbWUiOiLluq3liY3kupHokL0iLCJleHAiOjE1NzYyOTI1Mzd9.LlyCCBeW4f7fjU3LmE7cA8W7aNB1BXp23Yv9WQJouCRCtoD46GiXQAHn2kezuzuPfp2u5G0OXOIeahHtnvRMSDjtQFJ6s-cZcKNupJPOPK8BzuEnladx0ilcrSr5TeWNxujg-svSz5EJRwWj8KbRKhQluohpAg0VhERjJjD5wTY";

        UserInfo userInfo = JwtUtils.getObjectFromToken(token, RasUtils.getPublicKey(pubKeyPath), UserInfo.class);
        System.out.println(userInfo);
    }
}

密碼加密與微服務鑒權java JWT使用方法是什么

密碼加密與微服務鑒權java JWT使用方法是什么

5、JWT token組成

JWT的token包含三部分數據:頭部、載荷、簽名。

名稱描述組成部分
頭部(Header)通常頭部有兩部分信息1. 聲明類型,這里是JW2. 加密算法,自定義
載荷(Payload)就是有效數據1. 用戶身份信息2. 注冊聲明
簽名(Signature)整個數據的認證信息一般根據前兩步的數據,再加上服務的的密鑰(secret),通過加密算法生成。用于驗證整個數據完整和可靠性
  • 生成的數據格式

密碼加密與微服務鑒權java JWT使用方法是什么

感謝各位的閱讀,以上就是“密碼加密與微服務鑒權java JWT使用方法是什么”的內容了,經過本文的學習后,相信大家對密碼加密與微服務鑒權java JWT使用方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

岱山县| 临漳县| 浦城县| 晴隆县| 湟中县| 平罗县| 永川市| 长宁区| 永和县| 梁平县| 苏尼特右旗| 綦江县| 蓬莱市| 肃南| 马龙县| 衡东县| 杭锦后旗| 托里县| 岱山县| 项城市| 肃北| 涡阳县| 玉林市| 故城县| 奉化市| 台前县| 沙坪坝区| 礼泉县| 类乌齐县| 图们市| 辉县市| 保山市| 永川市| 穆棱市| 临潭县| 河源市| 舒城县| 托里县| 汶上县| 河曲县| 平果县|