你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

2021-11-19-权限管理

2021/11/21 23:28:28

目录

  • JWT
    • JWT组成
    • JWT对比传统token认证
    • JWT使用
    • JWT测试
  • 用户角色管理
    • RBAC模型
  • 搭建授权中心
  • 搭建资源中心
  • 登录功能

JWT

Json web token (JWT), 是为了在⽹络应⽤环境间传递声明⽽执⾏的⼀种基于JSON的开放标准((RFC 7519).定义了⼀种简洁的,⾃包含的⽅法⽤于通信双⽅之间以JSON对象的形式安全的传递信息。因为数 字签名的存在,这些信息是可信的,JWT可以使⽤HMAC算法或者是RSA的公私秘钥对进⾏签名。

JWT组成

示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9`.`eyJpZCI6IjU3ZmVmMTY0ZTU0YWY2NGZmYz UzZGJkNSIsInhzcmYiOiI0ZWE1YzUwOGE2NTY2ZTc2MjQwNTQzZjhmZWIwNmZkNDU3Nzc3YmUz OTU0OWM0MDE2NDM2YWZkYTY1ZDIzMzBlIiwiaWF0IjoxNDc2NDI3OTMzfQ`.`PA3QjeyZSUh7H 0GfE0vJaKW4LjKJuC3dVLQiY4hii8s

Header头部
token类型和加密算法

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

Payload负载
存放信息的地⽅,你可以把⽤户 ID 等信息,常⽤的有 iss(签发者),exp(过期时间),sub(⾯向的⽤户),aud(接 收⽅),iat(签发时间)。

{ "iss": "lion1ou JWT", "iat": 1441593502, "exp": 1441594722, "aud": "www.example.com", "sub": "xxx@163.com" }

Signature签名
前⾯两部分都是使⽤ Base64 进⾏编码的,即前端可以解开知道⾥⾯的信息。Signature 需要使⽤编码后的 header 和 payload 以及我们提供的⼀个密钥,然后使⽤ header 中指定的签名算法(HS256)进 ⾏签名。签名的作⽤是保证 JWT 没有被篡改过。

JWT对比传统token认证

传统token认证
在这里插入图片描述
JWT认证
在这里插入图片描述
传统的授权模式性能低下,每次都需要请求授权服务校验令牌合法性,我们可以利⽤公钥私 钥完成对令牌的加密,如果加密解密成功,则表示令牌合法,如果加密解密失败,则表示令牌⽆ 效不合法,合法则允许访问资源服务器的资源,解密失败,则不允许访问资源服务器资源

JWT使用

公钥和私钥
授权中心和资源中心持有私钥和公钥
授权中心颁发令牌、私钥签名
资源中心验证令牌、公钥验签
公钥和私钥生成 keytool⼯具⽣成公钥私钥证书

keytool -genkeypair -alias xxxx -keyalg RSA -keypass xxxxxx -keystore xxxx.jks -storepass xxxxxx
keytool -importkeystore -srckeystore xxxx.jks -destkeystore xxxx.jks -deststoretype pkcs12

-alias:密钥的别名;-keyalg:使⽤的hash算法; -keypass:密钥的访问密码; -keystore:密钥库⽂件名; -storepass:密钥库的访问密码;
查询证书信息

keytool -list -keystore xxxx.jks

openssl导出公钥
安装 openssl:http://slproweb.com/products/Win32OpenSSL.html
配置环境变量

keytool -list -rfc --keystore xxxx.jks | openssl x509 -inform pem -pubkey

截取保存为public.key

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu/0tAUy6igNeEmaCZPG3
FIkt5T2uqecUlA6WNtFRTSosIiQjX0iA9s+LiOqzmCOm7k9JFjMTSRcmaRMjpTMb
dmmBuDvDa92BOp6lGGT4vT3pJABFs6gdktqBMh0WyoLkOILRk9aO1KRQOHqb9Rfu
if3oyiE1tF0dTYp/wR4T8CYd1p19Qu2LLAFwb5kEuzp8HVDcbt/m1C8Rw4eBla8R
FXNpx5dBjQ8hNsTaDg9byNj+PnMVD5ufUDMw7tjG+1NCJotNzVxrrwLfsJYbCHFp
9YQNpE9ZxMivDV6pM0vc6P/jsLQzmtW5eLDwNl+Usz3zoFT3CeBdrFN4P5W0A5tX
IQIDAQAB
-----END PUBLIC KEY-----

JWT测试

oauth2依赖

<!--oauth2-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt</artifactId>
</dependency>

测试代码

public class JWTTest {
    //⽣成⼀个jwt令牌
    @Test
    public void testCreateJwt() throws Exception {
        //证书⽂件
        String key_location = "xxxx.jks";
        //密钥库密码
        String keystore_password = "xxxxxx";
        // 访问证书路径
        ClassPathResource resource = new ClassPathResource(key_location);
        //密钥⼯⼚
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource, keystore_password.toCharArray());
        //密钥的密码,此密码和别名要匹配
        String keypassword = "xxxxxx";
        //密钥别名
        String alias = "xxxx";
        //密钥对(密钥和公钥)
        KeyPair keyPair = keyStoreKeyFactory.getKeyPair(alias, keypassword.toCharArray());
        //私钥
        RSAPrivateKey aPrivate = (RSAPrivateKey) keyPair.getPrivate();
        //定义payload信息
        Map<String, Object> tokenMap = new HashMap<String, Object>();
        tokenMap.put("id", "123");
        tokenMap.put("name", "xxxx");
        tokenMap.put("roles", "r01,r02");
        tokenMap.put("ext", "1");
        //⽣成jwt令牌
        Jwt jwt = JwtHelper.encode(new ObjectMapper().writeValueAsString(tokenMap), new RsaSigner(aPrivate));
        //取出jwt令牌
        String token = jwt.getEncoded();
        System.out.println(token);
    }

    //资源服务使⽤公钥验证jwt的合法性,并对jwt解码
    @Test
    public void testVerify() {
        //jwt令牌
        String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHQiOiIxIiwicm9sZXMiOiJyMDEscjAyIiwibmFtZSI6ImNoZHh5emgiLCJpZCI6IjEyMyJ9.sRE_hwXuSW6NXpk8qnhJVxFqHar_p9qfXgayExeaLHzwJ4bR-On4zo1v0o811a9OZpDy5OeRUc9Vf6Z_lU1ob0tSVo6L382Inudld6hftJFf0F5t0vC8bPQ7irLKLa3rHh02QhiU4upkZLScX0SqjDwRXZqibU7hBRqUuyc2m01PA4rM85P7U2tswSyob8rT2LvfK3ZtR0PT4AkgfRlVyPhD2LUeddM7jJSlUIobRdD08gxWZFr6HVco10R2197Xn57ZrkXUZs7AOYT_E2MlbBxEFXAZeWuV3fdMxf8uZ27sLNEncc7pu2PFExbZUPtQjedpbyZkJIcNc3rmQiQtuA";
        //公钥
        String publickey = "-----BEGIN PUBLIC KEY-----\n" +
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu/0tAUy6igNeEmaCZPG3\n" +
                "FIkt5T2uqecUlA6WNtFRTSosIiQjX0iA9s+LiOqzmCOm7k9JFjMTSRcmaRMjpTMb\n" +
                "dmmBuDvDa92BOp6lGGT4vT3pJABFs6gdktqBMh0WyoLkOILRk9aO1KRQOHqb9Rfu\n" +
                "if3oyiE1tF0dTYp/wR4T8CYd1p19Qu2LLAFwb5kEuzp8HVDcbt/m1C8Rw4eBla8R\n" +
                "FXNpx5dBjQ8hNsTaDg9byNj+PnMVD5ufUDMw7tjG+1NCJotNzVxrrwLfsJYbCHFp\n" +
                "9YQNpE9ZxMivDV6pM0vc6P/jsLQzmtW5eLDwNl+Usz3zoFT3CeBdrFN4P5W0A5tX\n" +
                "IQIDAQAB\n" +
                "-----END PUBLIC KEY-----";
        //校验jwt
        Jwt jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(publickey));
        //获取jwt原始内容
        String claims = jwt.getClaims();
        System.out.println(claims);
        try {
            Map<String, String> map = new ObjectMapper().readValue(claims, Map.class);
            System.out.println(map.get("name"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

用户角色管理

RBAC模型

RBAC(基于⻆⾊的权限控制 role base access control)是⼀种设计模式,是⽤来设计和管 理权限相关数据的⼀种模型
在这里插入图片描述

搭建授权中心

搭建资源中心

登录功能