1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        JWT 和 JJWT,別再傻傻分不清了!

        共 10312字,需瀏覽 21分鐘

         ·

        2021-10-21 11:38

        點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)??

        jwt是什么?

        JWTs是JSON對(duì)象的編碼表示。JSON對(duì)象由零或多個(gè)名稱/值對(duì)組成,其中名稱為字符串,值為任意JSON值。

        JWT有助于在clear(例如在URL中)發(fā)送這樣的信息,可以被信任為不可讀(即加密的)、不可修改的(即簽名)和URL - safe(即Base64編碼的)。

        jwt的組成

        • Header: 標(biāo)題包含了令牌的元數(shù)據(jù),并且在最小包含簽名和/或加密算法的類型
        • Claims: Claims包含您想要簽署的任何信息
        • JSON Web Signature (JWS): 在header中指定的使用該算法的數(shù)字簽名和聲明

        例如:

        Header:

        {
        ??"alg":?"HS256",
        ??"typ":?"JWT"
        }

        Claims:

        {
        ??"sub":?"1234567890",
        ??"name":?"John?Doe",
        ??"admin":?true
        }

        Signature:

        base64UrlEncode(Header)?+?"."?+?base64UrlEncode(Claims),

        加密生成的token:

        圖片

        如何保證 JWT 安全

        有很多庫(kù)可以幫助您創(chuàng)建和驗(yàn)證JWT,但是當(dāng)使用JWT時(shí),仍然可以做一些事情來(lái)限制您的安全風(fēng)險(xiǎn)。在您信任JWT中的任何信息之前,請(qǐng)始終驗(yàn)證簽名。這應(yīng)該是給定的。

        換句話說(shuō),如果您正在傳遞一個(gè)秘密簽名密鑰到驗(yàn)證簽名的方法,并且簽名算法被設(shè)置為“none”,那么它應(yīng)該失敗驗(yàn)證。

        確保簽名的秘密簽名,用于計(jì)算和驗(yàn)證簽名。秘密簽名密鑰只能由發(fā)行者和消費(fèi)者訪問(wèn),不能在這兩方之外訪問(wèn)。

        不要在JWT中包含任何敏感數(shù)據(jù)。這些令牌通常是用來(lái)防止操作(未加密)的,因此索賠中的數(shù)據(jù)可以很容易地解碼和讀取。

        如果您擔(dān)心重播攻擊,包括一個(gè)nonce(jti索賠)、過(guò)期時(shí)間(exp索賠)和創(chuàng)建時(shí)間(iat索賠)。這些在JWT規(guī)范中定義得很好。

        圖片

        jwt的框架:JJWT

        JJWT是一個(gè)提供端到端的JWT創(chuàng)建和驗(yàn)證的Java庫(kù)。永遠(yuǎn)免費(fèi)和開源(Apache License,版本2.0),JJWT很容易使用和理解。它被設(shè)計(jì)成一個(gè)以建筑為中心的流暢界面,隱藏了它的大部分復(fù)雜性。

        • JJWT的目標(biāo)是最容易使用和理解用于在JVM上創(chuàng)建和驗(yàn)證JSON Web令牌(JWTs)的庫(kù)。
        • JJWT是基于JWT、JWS、JWE、JWK和JWA RFC規(guī)范的Java實(shí)現(xiàn)。
        • JJWT還添加了一些不屬于規(guī)范的便利擴(kuò)展,比如JWT壓縮和索賠強(qiáng)制。

        規(guī)范兼容:

        • 創(chuàng)建和解析明文壓縮JWTs
        • 創(chuàng)建、解析和驗(yàn)證所有標(biāo)準(zhǔn)JWS算法的數(shù)字簽名緊湊JWTs(又稱JWSs):
        • HS256: HMAC using SHA-256
        • HS384: HMAC using SHA-384
        • HS512: HMAC using SHA-512
        • RS256: RSASSA-PKCS-v1_5 using SHA-256
        • RS384: RSASSA-PKCS-v1_5 using SHA-384
        • RS512: RSASSA-PKCS-v1_5 using SHA-512
        • PS256: RSASSA-PSS using SHA-256 and MGF1 with SHA-256
        • PS384: RSASSA-PSS using SHA-384 and MGF1 with SHA-384
        • PS512: RSASSA-PSS using SHA-512 and MGF1 with SHA-512
        • ES256: ECDSA using P-256 and SHA-256
        • ES384: ECDSA using P-384 and SHA-384
        • ES512: ECDSA using P-521 and SHA-512

        這里以github上的demo演示,理解原理,集成到自己項(xiàng)目中即可。

        應(yīng)用采用 spring boot + angular + jwt

        結(jié)構(gòu)圖

        圖片

        Maven 引進(jìn) : pom.xml

        "http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        ????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd">
        ????4.0.0
        ????com.nibado.example
        ????jwt-angular-spring
        ????0.0.2-SNAPSHOT
        ????
        ????????1.8
        ????????1.8

        ????????2.4
        ????????0.6.0
        ????????4.12
        ????????1.5.3.RELEASE
        ????


        ????
        ????????
        ????????????
        ????????????????org.springframework.boot
        ????????????????spring-boot-maven-plugin
        ????????????????${spring.boot.version}
        ????????????????
        ????????????????????
        ????????????????????????
        ????????????????????????????repackage
        ????????????????????????

        ????????????????????

        ????????????????

        ????????????

        ????????

        ????


        ????
        ????????
        ????????????org.springframework.boot
        ????????????spring-boot-starter-web
        ????????????${spring.boot.version}
        ????????

        ????????
        ????????????commons-io
        ????????????commons-io
        ????????????${commons.io.version}
        ????????

        ????????
        ????????????io.jsonwebtoken
        ????????????jjwt
        ????????????${jjwt.version}
        ????????

        ????????
        ????????????junit
        ????????????junit
        ????????????${junit.version}
        ????????

        ????


        WebApplication.java

        package?com.nibado.example.jwtangspr;

        import?org.springframework.boot.SpringApplication;
        import?org.springframework.boot.autoconfigure.EnableAutoConfiguration;
        import?org.springframework.boot.web.servlet.FilterRegistrationBean;
        import?org.springframework.context.annotation.Bean;
        import?org.springframework.context.annotation.ComponentScan;
        import?org.springframework.context.annotation.Configuration;

        @EnableAutoConfiguration
        @ComponentScan
        @Configuration
        public?class?WebApplication?{
        ?
        ????//過(guò)濾器
        ????@Bean
        ????public?FilterRegistrationBean?jwtFilter()?{
        ????????final?FilterRegistrationBean?registrationBean?=?new?FilterRegistrationBean();
        ????????registrationBean.setFilter(new?JwtFilter());
        ????????registrationBean.addUrlPatterns("/api/*");
        ????????return?registrationBean;
        ????}

        ????public?static?void?main(final?String[]?args)?throws?Exception?{
        ????????SpringApplication.run(WebApplication.class,?args);
        ????}

        }

        JwtFilter.java

        package?com.nibado.example.jwtangspr;

        import?java.io.IOException;

        import?javax.servlet.FilterChain;
        import?javax.servlet.ServletException;
        import?javax.servlet.ServletRequest;
        import?javax.servlet.ServletResponse;
        import?javax.servlet.http.HttpServletRequest;

        import?org.springframework.web.filter.GenericFilterBean;

        import?io.jsonwebtoken.Claims;
        import?io.jsonwebtoken.Jwts;
        import?io.jsonwebtoken.SignatureException;

        public?class?JwtFilter?extends?GenericFilterBean?{

        ????@Override
        ????public?void?doFilter(final?ServletRequest?req,
        ?????????????????????????final?ServletResponse?res,
        ?????????????????????????final?FilterChain?chain)?throws?IOException,?ServletException?{
        ????????final?HttpServletRequest?request?=?(HttpServletRequest)?req;

        ????????//客戶端將token封裝在請(qǐng)求頭中,格式為(Bearer后加空格):Authorization:Bearer +token
        ????????final?String?authHeader?=?request.getHeader("Authorization");
        ????????if?(authHeader?==?null?||?!authHeader.startsWith("Bearer?"))?{
        ????????????throw?new?ServletException("Missing?or?invalid?Authorization?header.");
        ????????}

        ????????//去除Bearer?后部分
        ????????final?String?token?=?authHeader.substring(7);

        ????????try?{
        ?????????//解密token,拿到里面的對(duì)象claims
        ????????????final?Claims?claims?=?Jwts.parser().setSigningKey("secretkey")
        ????????????????.parseClaimsJws(token).getBody();
        ????????????//將對(duì)象傳遞給下一個(gè)請(qǐng)求
        ????????????request.setAttribute("claims",?claims);
        ????????}
        ????????catch?(final?SignatureException?e)?{
        ????????????throw?new?ServletException("Invalid?token.");
        ????????}

        ????????chain.doFilter(req,?res);
        ????}

        }

        UserController.java

        package?com.nibado.example.jwtangspr;

        import?java.util.Arrays;
        import?java.util.Date;
        import?java.util.HashMap;
        import?java.util.List;
        import?java.util.Map;

        import?javax.servlet.ServletException;

        import?org.springframework.web.bind.annotation.RequestBody;
        import?org.springframework.web.bind.annotation.RequestMapping;
        import?org.springframework.web.bind.annotation.RequestMethod;
        import?org.springframework.web.bind.annotation.RestController;

        import?io.jsonwebtoken.Jwts;
        import?io.jsonwebtoken.SignatureAlgorithm;

        @RestController
        @RequestMapping("/user")
        public?class?UserController?{

        ?//這里模擬數(shù)據(jù)庫(kù)
        ????private?final?Map>?userDb?=?new?HashMap<>();

        ????@SuppressWarnings("unused")
        ????private?static?class?UserLogin?{
        ????????public?String?name;
        ????????public?String?password;
        ????}
        ????
        ????public?UserController()?{
        ????????userDb.put("tom",?Arrays.asList("user"));
        ????????userDb.put("wen",?Arrays.asList("user",?"admin"));
        ????}
        ????/*以上是模擬數(shù)據(jù)庫(kù),并往數(shù)據(jù)庫(kù)插入tom和sally兩條記錄*/
        ????
        ????
        ????@RequestMapping(value?=?"login",?method?=?RequestMethod.POST)
        ????public?LoginResponse?login(@RequestBody?final?UserLogin?login)
        ????????throws?ServletException?{
        ????????if?(login.name?==?null?||?!userDb.containsKey(login.name))?{
        ????????????throw?new?ServletException("Invalid?login");
        ????????}
        ????????
        ????????//加密生成token
        ????????return?new?LoginResponse(Jwts.builder().setSubject(login.name)
        ????????????.claim("roles",?userDb.get(login.name)).setIssuedAt(new?Date())
        ????????????.signWith(SignatureAlgorithm.HS256,?"secretkey").compact());
        ????}

        ????@SuppressWarnings("unused")
        ????private?static?class?LoginResponse?{
        ????????public?String?token;

        ????????public?LoginResponse(final?String?token)?{
        ????????????this.token?=?token;
        ????????}
        ????}
        }

        ApiController.java

        package?com.nibado.example.jwtangspr;

        import?io.jsonwebtoken.Claims;

        import?java.util.List;

        import?javax.servlet.ServletException;
        import?javax.servlet.http.HttpServletRequest;

        import?org.springframework.web.bind.annotation.PathVariable;
        import?org.springframework.web.bind.annotation.RequestMapping;
        import?org.springframework.web.bind.annotation.RequestMethod;
        import?org.springframework.web.bind.annotation.RestController;

        @RestController
        @RequestMapping("/api")
        public?class?ApiController?{
        ?@SuppressWarnings("unchecked")
        ?@RequestMapping(value?=?"role/{role}",?method?=?RequestMethod.GET)
        ?public?Boolean?login(@PathVariable?final?String?role,
        ???final?HttpServletRequest?request)?throws?ServletException?{
        ??final?Claims?claims?=?(Claims)?request.getAttribute("claims");
        ??return?((List)?claims.get("roles")).contains(role);
        ?}
        }

        index.html


        "myApp">

        ????"utf-8"/>
        ????"X-UA-Compatible"?content="IE=edge,chrome=1"/>
        ????JSON?Web?Token?/?AngularJS?/?Spring?Boot?example
        ????"description"?content="">
        ????"viewport"?content="width=device-width">
        ????"stylesheet"?href="libs/bootstrap/css/bootstrap.css">
        ????
        ????
        ????
        ????


        "container"?ng-controller='MainCtrl'>
        ?

        {{greeting}}


        ?"!loggedIn()">
        ??Please?log?in?(tom?and?sally?are?valid?names)

        ??"login()">
        ???Username:?type="text"?ng-model="userName"/>type="submit"?value="Login"/>
        ??
        ?

        ?"alert?alert-danger"?role="alert"?ng-show="error.data.message">
        ???"glyphicon?glyphicon-exclamation-sign"?aria-hidden="true">
        ???"sr-only">Error:
        ???{{error.data.message}}
        ?
        ?
        ?"loggedIn()">
        ??"row">
        ???"col-md-6">
        ????

        "label?label-success">Success!?Welcome?{{userName}}


        ?????"logout()">(logout)
        ???

        ???"col-md-4">
        ???"row?header">
        ???"col-sm-4">{{userName}}?is?a

        ??

        ??"row">
        ???"col-sm-2">User
        ???"col-sm-2">"glyphicon?glyphicon-ok"?aria-hidden="true"?ng-show="roleUser">
        ??
        ??"row">
        ???"col-sm-2">Admin
        ???"col-sm-2">"glyphicon?glyphicon-ok"?aria-hidden="true"?ng-show="roleAdmin">
        ???
        ??"row">
        ???"col-sm-2">Foo
        ???"col-sm-2">"glyphicon?glyphicon-ok"?aria-hidden="true"?ng-show="roleFoo">
        ??????
        ???
        ??
        ?



        app.js

        var?appModule?=?angular.module('myApp',?[]);

        appModule.controller('MainCtrl',?['mainService','$scope','$http',
        ????????function(mainService,?$scope,?$http)?{
        ????????????$scope.greeting?=?'Welcome?to?the?JSON?Web?Token?/?AngularJR?/?Spring?example!';
        ????????????$scope.token?=?null;
        ????????????$scope.error?=?null;
        ????????????$scope.roleUser?=?false;
        ????????????$scope.roleAdmin?=?false;
        ????????????$scope.roleFoo?=?false;

        ????????????$scope.login?=?function()?{
        ????????????????$scope.error?=?null;
        ????????????????mainService.login($scope.userName).then(function(token)?{
        ????????????????????$scope.token?=?token;
        ????????????????????$http.defaults.headers.common.Authorization?=?'Bearer?'?+?token;
        ????????????????????$scope.checkRoles();
        ????????????????},
        ????????????????function(error){
        ????????????????????$scope.error?=?error
        ????????????????????$scope.userName?=?'';
        ????????????????});
        ????????????}

        ????????????$scope.checkRoles?=?function()?{
        ????????????????mainService.hasRole('user').then(function(user)?{$scope.roleUser?=?user});
        ????????????????mainService.hasRole('admin').then(function(admin)?{$scope.roleAdmin?=?admin});
        ????????????????mainService.hasRole('foo').then(function(foo)?{$scope.roleFoo?=?foo});
        ????????????}

        ????????????$scope.logout?=?function()?{
        ????????????????$scope.userName?=?'';
        ????????????????$scope.token?=?null;
        ????????????????$http.defaults.headers.common.Authorization?=?'';
        ????????????}

        ????????????$scope.loggedIn?=?function()?{
        ????????????????return?$scope.token?!==?null;
        ????????????}
        ????????}?]);



        appModule.service('mainService',?function($http)?{
        ????return?{
        ????????login?:?function(username)?{
        ????????????return?$http.post('/user/login',?{name:?username}).then(function(response)?{
        ????????????????return?response.data.token;
        ????????????});
        ????????},

        ????????hasRole?:?function(role)?{
        ????????????return?$http.get('/api/role/'?+?role).then(function(response){
        ????????????????console.log(response);
        ????????????????return?response.data;
        ????????????});
        ????????}
        ????};
        });

        運(yùn)行應(yīng)用

        圖片

        效果

        圖片
        圖片

        原文鏈接:https://blog.csdn.net/change_on/article/details/76279441

        版權(quán)聲明:本文為CSDN博主「J_小浩子」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

        1.?你用什么軟件做筆記?

        2.?WebSocket 集群解決方案

        3.?MySQL 跨庫(kù)分頁(yè)、分表分頁(yè)之后,面臨的一些新問(wèn)題

        4.?40 個(gè) Spring Boot 常用注解,你知道幾個(gè)?

        最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊(cè),覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。

        獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

        文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。

        謝謝支持喲 (*^__^*)


        瀏覽 26
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            瑟瑟爱视频 | 日韩精品一区二区三区swag | 丝袜护士给我脚交取精 | 婷婷五月天啪啪 | 欧美一级片在线电影 | 久久精品成人视频 | 另类专区亚洲 | 懂色av蜜臀av粉嫩av喷吹 | 黄色污污网站在线观看 | 成人免费性爱视频 |