前面已经学习了Vert.x web的基础接口,本文主要讲解引入jwt为接口认证/鉴权。引用之前创建的项目《Vert.x 4 Web应用初识》,加入jwt token相关依赖 io.vertx:vertx-auth-jwt,开始了Vert.x中的Jwt认证之旅。
maven pom.xml 依赖节点引入jwt相关依赖
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-auth-jwt</artifactId>
<version>4.5.9</version>
</dependency>
生成rsa密钥对参考 《OpenSSL 工具生成RSA密钥对》这里只需要最简单不加密的RSA密钥对就行。生成好以后复制到项目中,位置参考下面项目结构图
在MainVerticle,start中创建jwt的认证提供者
代码聚焦
//采用RSA256非对称加密
Buffer privateKeyBuf = vertx.fileSystem().readFileBlocking("certs/rsa_private_2048.pem");//相对于resources目录
Buffer publicKeyBuf = vertx.fileSystem().readFileBlocking("certs/rsa_public_2048.pem");
JWTAuth jwtAuth = JWTAuth.create(vertx,
new JWTAuthOptions()
.addPubSecKey(
new PubSecKeyOptions()
.setAlgorithm("RS256")
.setBuffer(publicKeyBuf)
)
.addPubSecKey(
new PubSecKeyOptions()
.setAlgorithm("RS256")
.setBuffer(privateKeyBuf)
)
);
注意点:
模拟用户输入用户名和密码登录,成功返回toen字符串
代码聚焦
router.post("/login").handler(ctx->{
String username = ctx.request().getParam("username");
String password = ctx.request().getParam("password");
if ("admin".equals(username) && "admin".equals(password)) {
//初始化几个权限和角色数据(实际应用这里应该调用数据库查询对应用户的角色权限)
List<String> roles = new ArrayList<>();
roles.add("admin");
roles.add("user");
List<String> permissions = new ArrayList<>();
permissions.add("list_products");
ctx.response()
.end(jwtAuth.generateToken(
new JsonObject()
.put("permissions", permissions)
.put("roles",roles)
.put("username", username)
.put("someKey", "someValue")
,
new JWTOptions()
.setIgnoreExpiration(false)
.setExpiresInMinutes(30)
.setAlgorithm("RS256") //默认值是HS256,所有必须指定算法RS256
)
);
}else {
ctx.fail(401);
}
});
以上代码实现了登录业务,包含
使用postman工具测试
以上操图作可以看到,与我们预期结果一致。
代码聚焦
//创建token后则访问 需要认证(登录)的资源
AuthenticationHandler authenticationHandler = JWTAuthHandler.create(jwtAuth);
router.route("/protected/*").handler(authenticationHandler);
router.route("/protected/info").handler(ctx ->{
ctx.response()
.putHeader("content-type", "text/plain")
.end("protected info !");
});
//token 请求时候放入头部 Authorization Bearer <token>
此处jwtAuth 就是上面创建的jwtAuth RSA
上方代码表示访问/protected/
开头的接口都需要认证才行否则返回401
使用postman工具测试
首先是直接访问接口/protected/info
直接访问需要认证的接口,可以看到上方返回401状态码并返回未认证/未登录,与预期结果一致。
接下来设置token,使用认证的token来访问接口。
首先调用登录生成token,然后复制到下图的token位置
再次请求
从上图可以看到携带token再次请求接口成功获得了响应内容,与预期结果一致。
代码聚焦
//意思是从jwt token的obj中拿出permissions节点进行权限判断
AuthorizationProvider authorizationProvider = JWTAuthorization.create("permissions");
//[/protected/list_products]开头的路径需要list_products权限才能访问,从authorizationProvider表示jwt中拿出permission节点进行和list_products对比
router.route("/protected/list_products*").handler(
AuthorizationHandler.create(PermissionBasedAuthorization.create("list_products"))
.addAuthorizationProvider(authorizationProvider)
);
router.route("/protected/list_products").handler(ctx->{
ctx.response()
.putHeader("content-type", "text/plain")
.end("list_products Go !");
});
//指定地址指定权限
router.route("/protected/list_products/one").handler(
AuthorizationHandler.create(PermissionBasedAuthorization.create("one_products"))
.addAuthorizationProvider(authorizationProvider)
).handler(ctx->{
ctx.response()
.putHeader("content-type", "text/plain")
.end("one_products Go !");
});
上方代码指定接口权限对应
/protected/list_products*
开头需要list_products
权限/protected/list_products
需要list_products
权限/protected/list_products/one
需要list_products
和one_products
权限使用postman工具测试验证
注意:需要授权的接口是肯定需要认证的,所以以下接口测试都将默认携带上面生成的token
访问list_products接口成功,与预期结果一致 (token中包含list_products
权限,有疑问可以返回查看上面的token生成部分)
访问one接口,从上图可以看到403了,与预期结果一致(token中没有包含one_products权限,有疑问可以返回查看上面的token生成部分)
这里指定角色代码授权访问其实和权限相差不大,就是从token取值的节点变成了另外一个(同时节点名称也是可以自定义的)
代码聚焦
//意思是从jwt token的obj中拿出roles节点进行权限判断
AuthorizationProvider authorizationProviderRoles = JWTAuthorization.create("roles");
//指定路径需要admin role 才能访问
router.route("/protected/setting/get").handler(
AuthorizationHandler.create(PermissionBasedAuthorization.create("admin"))
.addAuthorizationProvider(authorizationProviderRoles)
).handler(ctx->{
ctx.response()
.putHeader("content-type", "text/plain")
.end("Get setting !");
});
以上代码表示需要admin的角色才能访问该接口,我们上面初始化的token是包含admin的所以可以直接访问,参考下方请求图
https://www.leftso.com/article/2408131134214153.html