1. 首页 » 生活常识

kwm格式转换mp3文件方法教程

什么是jwt?

以下是官网解释

JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),它定义了一种紧凑且自包含的方式,用于在各方之间作为 JSON 对象安全地传输信息。该信息可以被验证和信任,因为它是经过数字签名的。JWT 可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

虽然 JWT 可以加密以在各方之间提供保密,但我们将重点关注签名令牌。签名令牌可以验证其中包含的声明的完整性,而加密令牌则对其他方隐藏这些声明。当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。

官网: https://jwt.io/

标准: https://tools.ietf.org/html/rfc7519

JWT令牌的优点:

jwt基于json,非常方便解析。可以在令牌中自定义丰富的内容,易扩展。通过非对称加密算法及数字签名技术,JWT防止篡改,安全性高。资源服务使用JWT可不依赖授权服务即可完成授权。

缺点:

JWT令牌较长,占存储空间比较大。

jwt应用场景

授权:这是使用 JWT 最常见的场景。用户登录后,每个后续请求都将包含 JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销很小,并且能够轻松跨不同域使用。信息交换:JSON Web Tokens 是一种在各方之间安全传输信息的好方法。因为 JWT 可以被签名——例如,使用公钥/私钥对——你可以确定发件人就是他们所说的那样。此外,由于使用标头和有效负载计算签名,因此您还可以验证内容是否未被篡改。

JWT组成

一个JWT实际上就是一个字符串,它由用(.)分割的三部分组成,头部(header)、载荷(payload)与签名 (signature)。

因此,JWT 通常如下所示。

xxxxx.yyyyy.zzzzz

接下来分别介绍这三个部分

头部(**header)**

头部用于描述关于该JWT的最基本的信息:类型(即JWT)以及签名所用的算法(如 HMACSHA256或RSA)等。

这也可以被表示成一个JSON对象:

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

然后,这个 JSON 被Base64Url编码以形成 JWT 的第一部分。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 

载荷(**payload)**

存放有效信息的地方,包含三个部分:

标准中注册的声明(建议但不强制使用),例如,iss: jwt签发者,sub: jwt所面向的用户 ,aud: 接收jwt的一方 ,exp: jwt的过期时间,这个过期时间必须要大于签发时间 ,nbf: 定义在什么时间之前,该jwt都是不可用的,iat: jwt的签发时间 ,jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。公共声明:公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不 建议添加敏感信息,因为该部分在客户端可解密。私有的声明 :私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,该部分信息可以归类为明文信息

定义一个有效载荷

{
  "sub": "1234567890",
  "name": "Jack",
  "iat": 1516239022
}

然后将其进行base64加密,得到Jwt的第二部分:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphY2siLCJpYXQiOjE1MTYyMzkwMjJ9

签名(**signature)**

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

header (base64加密后的)payload (base64加密后的)secret(密钥,在服务端)

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分:

hrInLPw3Fzh2QZMSTXNYBRQbB2_WdyW0Yuemp3_Ht_A

把这三个部分连在一起就得到一个完整的jwt

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphY2siLCJpYXQiOjE1MTYyMzkwMjJ9.hrInLPw3Fzh2QZMSTXNYBRQbB2_WdyW0Yuemp3_Ht_A

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的 签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。

jwt使用

是在请求头里加入Authorization,并加上Bearer标注:Authorization: Bearer

下图显示了如何获取 JWT 并将其用于访问 API 或资源:

spring security整合jwt oauth2

应用程序或客户端向授权服务器请求授权。当授权被授予时,授权服务器向应用程序返回一个访问令牌。应用程序使用访问令牌来访问受保护的资源(如 API)。

快速使用

JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。

引入依赖

  
            io.jsonwebtoken
            jjwt
            0.6.0
        
      

生成token


private static final String SECRETKEY="1111111";

@Test
public void test() {

    Map map = new HashMap();
    map.put("phone","13211111");
    map.put("email","11@qq.com");
    //创建一个JwtBuilder对象
    JwtBuilder jwtBuilder = Jwts.builder()
            //声明的标识{"jti":"666"}
            .setId("666")
            //主体,用户{"sub":"jack"}
            .setSubject("jack")
            //创建日期{"ita":"xxxxxx"}
            .setIssuedAt(new Date())
            //设置过期时间   10分钟
            .setExpiration(new Date(System.currentTimeMillis()+600*1000))
            //claims 有效载荷
            .addClaims(map)
            .claim("roles","admin")
            //签名手段,参数1:算法,参数2:密钥
            .signWith(SignatureAlgorithm.HS256, SECRETKEY);
    //获取token   jwt
    String token = jwtBuilder.compact();
    System.out.println(token);

    //三部分的base64解密
    String[] split = token.split("\\.");
    //{"alg":"HS256"}
    System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
    
    //{"jti":"666","sub":"jack","iat":1636896993,"exp":1636897053,"phone":"13211111",
    "email":"11@qq.com","roles":"admin","logo":"xxx.jpg"}
    System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
    //base64无法解密
    System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
}

验证解析token

public void testParseToken(){
    //token
    String token ="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI2NjYiLCJzdWIiOiJqYWNrIiwiaWF0IjoxNjM2ODk3NDk2LCJleHAiOjE2MzY4OTgwOTYsInBob25lIjoiMTMyMTExMTEiLCJlbWFpbCI6IjExQHFxLmNvbSIsInJvbGVzIjoiYWRtaW4iLCJsb2dvIjoieHh4LmpwZyJ9.VHZDARQFehcZZsp9Uurd4yWY_TwBwi8UVN01s3r7cfU";
    //解析token获取载荷中的声明对象
    Claims claims = Jwts.parser()
            .setSigningKey(SECRETKEY)
            .parseClaimsJws(token)
            .getBody();

    System.out.println("id:"+claims.getId());
    System.out.println("subject:"+claims.getSubject());
    System.out.println("issuedAt:"+claims.getIssuedAt());

    DateFormat sf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println("签发时间:"+sf.format(claims.getIssuedAt()));
    System.out.println("过期时间:"+sf.format(claims.getExpiration()));
    System.out.println("当前时间:"+sf.format(new Date()));

    System.out.println("roles:"+claims.get("roles"));
}

打印结果:

id:666
subject:jack
issuedAt:Sun Nov 14 21:44:56 CST 2021
签发时间:2021-11-14 21:44:56
过期时间:2021-11-14 21:54:56
当前时间:2021-11-14 21:45:30
roles:admin

Spring Security 整合Oauth2、JWT

 

    org.springframework.security 

    spring‐security‐jwt 

    1.0.9.RELEASE 

 

省略了spring security 配置

配置JwtTokenStore

@Configuration
public class JwtTokenStoreConfig {

    @Bean
    public TokenStore jwtTokenStore(){
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter accessTokenConverter = new
                JwtAccessTokenConverter();
        //配置JWT使用的秘钥
        accessTokenConverter.setSigningKey("111111");
        return accessTokenConverter;
    }

    @Bean
    public JwtTokenEnhancer jwtTokenEnhancer() {
        return new JwtTokenEnhancer();
    }
}

配置扩展jwt存储内容

public class JwtTokenEnhancer implements TokenEnhancer {

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken,
                                     OAuth2Authentication authentication) {
        Map info = new HashMap<>();
        info.put("phone", "1321111111");
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
        return accessToken;
    }
}

指定存储策略是jwt

@Autowired
@Qualifier("jwtTokenStore")
private TokenStore tokenStore;

@Autowired
private JwtAccessTokenConverter jwtAccessTokenConverter;

@Autowired
private JwtTokenEnhancer jwtTokenEnhancer;

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    //配置JWT的内容增强器
    TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
    List delegates = new ArrayList<>();
    delegates.add(jwtTokenEnhancer);
    delegates.add(jwtAccessTokenConverter);
    enhancerChain.setTokenEnhancers(delegates);
    
    endpoints.authenticationManager(authenticationManagerBean) //使用密码模式需要配置
            .tokenStore(tokenStore)  //配置存储令牌策略
            .accessTokenConverter(jwtAccessTokenConverter)
            .tokenEnhancer(enhancerChain) //配置tokenEnhancer
            .reuseRefreshTokens(false)  //refresh_token是否重复使用
            .userDetailsService(userService) //刷新令牌授权包含对用户信息的检查
            .allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST); //支持GET,POST请求
}

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    //允许表单认证
    security.allowFormAuthenticationForClients();
}

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        
        clients.inMemory()
                //配置client_id
                .withClient("client")
                //配置client-secret
                .secret(passwordEncoder.encode("111111"))
                //配置访问token的有效期
                .accessTokenValiditySeconds(3600)
                //配置刷新token的有效期
                .refreshTokenValiditySeconds(864000)
                //配置redirect_uri,用于授权成功后跳转
                .redirectUris("http://www.baidu.com")
                //配置申请的权限范围
                .scopes("all")
                /**
                 * 配置grant_type,表示授权类型
                 * authorization_code: 授权码
                 * password: 密码
                 * client_credentials: 客户端
                 * refresh_token: 更新令牌
                 */
                .authorizedGrantTypes("authorization_code","password","refresh_token");
    }

通过密码方式获取token

http://localhost:8080/oauth/token?grant_type=password&username=jack&password=123456&client_id=client&client_secret=123123&scope=all
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwaG9uZSI6IjEzMjExMTExMTEiLCJ1c2VyX25hbWUiOiJqYWNrIiwic2NvcGUiOlsiYWxsIl0sImV4cCI6MTYzNjkwNjU4MiwiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiYzA1ZWJlNzItMmU1Zi00OGJjLThhNzYtODAzMDIxNGM3MzliIiwiY2xpZW50X2lkIjoiY2xpZW50In0.6DdtIkeR9inSuHAxSTo4lQvanDqrKJ0v8ke6ZzWQZdA","token_type":"bearer","refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwaG9uZSI6IjEzMjExMTExMTEiLCJ1c2VyX25hbWUiOiJqYWNrIiwic2NvcGUiOlsiYWxsIl0sImF0aSI6ImMwNWViZTcyLTJlNWYtNDhiYy04YTc2LTgwMzAyMTRjNzM5YiIsImV4cCI6MTYzNzc2Njk4MiwiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiOWJjMDkzM2ItMGZkNy00NTY2LWFhMTItYzlmMzYzNDBlZmY4IiwiY2xpZW50X2lkIjoiY2xpZW50In0.pcKNqiMZv4G9uKrv7P9qNYys6MQL0KJ-6MKz6HY9sbA","expires_in":3599,"scope":"all","phone":"1321111111","jti":"c05ebe72-2e5f-48bc-8a76-8030214c739b"}

使用token

http://localhost:8080/user/getUser?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwaG9uZSI6IjEzMjExMTExMTEiLCJ1c2VyX25hbWUiOiJqYWNrIiwic2NvcGUiOlsiYWxsIl0sImV4cCI6MTYzNjkwNjU4MiwiYXV0aG9yaXRpZXMiOlsiYWRtaW4iXSwianRpIjoiYzA1ZWJlNzItMmU1Zi00OGJjLThhNzYtODAzMDIxNGM3MzliIiwiY2xpZW50X2lkIjoiY2xpZW50In0.6DdtIkeR9inSuHAxSTo4lQvanDqrKJ0v8ke6ZzWQZdA

声明:本文由"麦兜"发布,不代表"破站"立场,转载联系作者并注明出处:https://www.848586.cn/119293.html