JWTワンポイントログイン
6435 ワード
JWTの紹介:
JWT、すなわちJSON Web Token(JWT)は、現在最も流行しているドメイン間認証ソリューションです.
JWTの構成:
JWTは実際には文字列であり、頭部(Header)、荷重(Payload)、署名(signature)の3つの部分から構成されている.
1, Header
{“typ”:“JWT”,“alg”:“HS256”}
このjsonのtypプロパティは、token文字列全体がJWT文字列であることを識別するために使用されます.そのalg属性は、このJWTの発行時に使用される署名と要約アルゴリズムを説明するために使用されます.
typとalg属性の全称は実はtypeとalgorithmで、それぞれタイプとアルゴリズムの意味です.3文字で表すのも、JWTの最終文字列の大きさを考慮したものです.
JWTという名前と一致しているので、3文字になります...typとalgはJWTで標準的に規定されている属性名です
2,Payload(負荷)
{“sub”:“123”,“name”:“Tom”,“admin”:true}
payloadは、JWT規格でclaimsと呼ばれているJWTによって伝達されるデータのセットであるjson構造の宣言を搬送するために使用されます.
プロパティ値ペアはclaim(要件)です.
各claimは、特定の意味と役割を表します.
3 signature
署名はヘッダとpayloadに対応するjson構造をbase 64 url符号化して得られた2つの列を英語の句点番号でつなぎ合わせ,ヘッダにalgが指定した署名アルゴリズムに基づいて生成する.
アルゴリズムが異なり、署名結果が異なります.alg:HS 256を例に、前の署名がどのように得られるかを説明します.
前述のalg利用可能な値の説明によれば、HS 256は、要約を生成するために使用されるHMACアルゴリズムとSHA 256アルゴリズムの2つのアルゴリズム、および要約をデジタル署名するために使用されるSHA 256アルゴリズムを含む.この2つのアルゴリズムはHMACSHA 256で総称することもできる.
JWTの検証プロセス
JWT検証の方法は実は簡単で、headerをbase 64 urlで復号すれば、JWTがどんなアルゴリズムで作った署名を知って、このアルゴリズムで、headerとpayloadに再び同じ論理で署名することができます.
この署名がJWT自体に含まれる3番目の部分の列と完全に同じかどうかを比較し、異なる限り、このJWTは改ざんされた列であると考えられ、当然検証に失敗した.
受信者が署名を生成するときは、JWT送信者と同じ鍵を使用する必要があります.
JWT結合springbootプロジェクト: pom.xml追加は、 testユニットテスト暗号化 testユニットテスト復号 JWT基本使用
tokenを生成するロジック:ログインに成功した後、jwtを使用してtokenを生成します.
Token検査
Springbootブロッキングのオン方法
ブロッキングを追加
JWT、すなわちJSON Web Token(JWT)は、現在最も流行しているドメイン間認証ソリューションです.
JWTの構成:
JWTは実際には文字列であり、頭部(Header)、荷重(Payload)、署名(signature)の3つの部分から構成されている.
1, Header
{“typ”:“JWT”,“alg”:“HS256”}
このjsonのtypプロパティは、token文字列全体がJWT文字列であることを識別するために使用されます.そのalg属性は、このJWTの発行時に使用される署名と要約アルゴリズムを説明するために使用されます.
typとalg属性の全称は実はtypeとalgorithmで、それぞれタイプとアルゴリズムの意味です.3文字で表すのも、JWTの最終文字列の大きさを考慮したものです.
JWTという名前と一致しているので、3文字になります...typとalgはJWTで標準的に規定されている属性名です
2,Payload(負荷)
{“sub”:“123”,“name”:“Tom”,“admin”:true}
payloadは、JWT規格でclaimsと呼ばれているJWTによって伝達されるデータのセットであるjson構造の宣言を搬送するために使用されます.
プロパティ値ペアはclaim(要件)です.
各claimは、特定の意味と役割を表します.
3 signature
署名はヘッダとpayloadに対応するjson構造をbase 64 url符号化して得られた2つの列を英語の句点番号でつなぎ合わせ,ヘッダにalgが指定した署名アルゴリズムに基づいて生成する.
アルゴリズムが異なり、署名結果が異なります.alg:HS 256を例に、前の署名がどのように得られるかを説明します.
前述のalg利用可能な値の説明によれば、HS 256は、要約を生成するために使用されるHMACアルゴリズムとSHA 256アルゴリズムの2つのアルゴリズム、および要約をデジタル署名するために使用されるSHA 256アルゴリズムを含む.この2つのアルゴリズムはHMACSHA 256で総称することもできる.
JWTの検証プロセス
JWT検証の方法は実は簡単で、headerをbase 64 urlで復号すれば、JWTがどんなアルゴリズムで作った署名を知って、このアルゴリズムで、headerとpayloadに再び同じ論理で署名することができます.
この署名がJWT自体に含まれる3番目の部分の列と完全に同じかどうかを比較し、異なる限り、このJWTは改ざんされた列であると考えられ、当然検証に失敗した.
受信者が署名を生成するときは、JWT送信者と同じ鍵を使用する必要があります.
JWT結合springbootプロジェクト:
com.auth0
java-jwt
3.8.1
io.jsonwebtoken
jjwt
0.9.1
@Test
public void testCase1(){
JwtBuilder builder = Jwts.builder();
JwtBuilder jwtBuilder = builder.setSubject("yangjingwen")
.signWith(SignatureAlgorithm.HS256, "qianfeng")
.claim("role", "admin")
.setExpiration(new Date(System.currentTimeMillis() + 60000))
.setIssuedAt(new Date());
String compact = jwtBuilder.compact();
System.out.println(compact);
}
@Test
public void testCase2(){
String token="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ5YW5namluZ3dlbiIsInJvbGUiOiJhZG1pbiIsI mV4cCI6MTU2MzI2ODUzNywiaWF0IjoxNTYzMjY4NDc3fQ.mHrESLyGONzlAXwOmRa U3gkVwFZ_pNqBUl7WcM2vviE";
String key="qianfeng";
Claims body = Jwts.parser().setSigningKey(key)
.parseClaimsJws(token).getBody();
String subject = body.getSubject();
Date issuedAt = body.getIssuedAt();
Date expiration = body.getExpiration();
}
tokenを生成するロジック:ログインに成功した後、jwtを使用してtokenを生成します.
// , token
String token = Jwts.builder().setSubject(userDTO.getUsername()) // ,
.setIssuedAt(new Date()) //token
.setExpiration(new Date(System.currentTimeMillis() + 60000)) //token
.setId(memeber.getMemeberId()) // ID
.setClaims(hashMap) //
.signWith(SignatureAlgorithm.HS256, "qianfeng") //
.compact();
Token検査
try {
JwtParser parser = Jwts.parser();
parser.setSigningKey("qianfeng");
Jws claimsJws = parser.parseClaimsJws(token);
Claims body = claimsJws.getBody();
String username = body.getSubject();
Object role = body.get("role");
return true;
} catch (ExpiredJwtException e) {
e.printStackTrace();
} catch (UnsupportedJwtException e) {
e.printStackTrace();
} catch (MalformedJwtException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
Springbootブロッキングのオン方法
package com.qianfeng.interceptor;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
*/
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getParameter("token");
try {
JwtParser parser = Jwts.parser();
parser.setSigningKey("qianfeng");
Jws claimsJws = parser.parseClaimsJws(token);
Claims body = claimsJws.getBody();
String username = body.getSubject();
Object role = body.get("role");
return true;
} catch (ExpiredJwtException e) {
e.printStackTrace();
} catch (UnsupportedJwtException e) {
e.printStackTrace();
} catch (MalformedJwtException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
ブロッキングを追加
package com.qianfeng.configuration;
import com.qianfeng.interceptor.LoginInterceptor;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
public class AppConfiguration implements WebMvcConfigurer {
@Resource
private LoginInterceptor loginInterceptor;
@Bean
@LoadBalanced
public RestTemplate provideRestTemplate(){
return new RestTemplate();
}
/**
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
}
}