认证/授权

Vert.x附带一些用于处理认证和授权的开箱即用的处理程序。

创建一个Auth处理程序

router.route().handler(CookieHandler.create());
router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));

AuthHandler basicAuthHandler = BasicAuthHandler.create(authProvider);

在您的应用程序中处理auth

对以/private开头的路径授权。

router.route().handler(CookieHandler.create());
router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));
router.route().handler(UserSessionHandler.create(authProvider));

AuthHandler basicAuthHandler = BasicAuthHandler.create(authProvider);

// All requests to paths starting with '/private/' will be protected
router.route("/private/*").handler(basicAuthHandler);

router.route("/someotherpath").handler(routingContext -> {

  // This will be public access - no login required

});

router.route("/private/somepath").handler(routingContext -> {

  // This will require a login

  // This will have the value true
  boolean isAuthenticated = routingContext.user() != null;

});

HTTP基本认证

如果访问需要授权的资源,会返回401的响应,提示用户登录。

重定向认证处理程序

如果用户没登录,会被定向到登录页面。

示例:

router.route().handler(CookieHandler.create());
router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)));
router.route().handler(UserSessionHandler.create(authProvider));

AuthHandler redirectAuthHandler = RedirectAuthHandler.create(authProvider);

// All requests to paths starting with '/private/' will be protected
router.route("/private/*").handler(redirectAuthHandler);

// Handle the actual login
// One of your pages must POST form login data
router.post("/login").handler(FormLoginHandler.create(authProvider));

// Set a static server to serve static resources, e.g. the login page
router.route().handler(StaticHandler.create());

router.route("/someotherpath").handler(routingContext -> {
  // This will be public access - no login required
});

router.route("/private/somepath").handler(routingContext -> {

  // This will require a login

  // This will have the value true
  boolean isAuthenticated = routingContext.user() != null;

});

JWT授权

没有权限的用户将被拒绝访问。

  • 发送令牌
  • 过滤请求

这种方式只能用HTTPS,不然会出现会话劫持攻击。

发送令牌示例

Router router = Router.router(vertx);

JsonObject authConfig = new JsonObject().put("keyStore", new JsonObject()
  .put("type", "jceks")
  .put("path", "keystore.jceks")
  .put("password", "secret"));

JWTAuth authProvider = JWTAuth.create(vertx, authConfig);

router.route("/login").handler(ctx -> {
  // this is an example, authentication should be done with another provider...
  if ("paulo".equals(ctx.request().getParam("username")) && "secret".equals(ctx.request().getParam("password"))) {
    ctx.response().end(authProvider.generateToken(new JsonObject().put("sub", "paulo"), new JWTOptions()));
  } else {
    ctx.fail(401);
  }
});

使用令牌

Router router = Router.router(vertx);

JsonObject authConfig = new JsonObject().put("keyStore", new JsonObject()
  .put("type", "jceks")
  .put("path", "keystore.jceks")
  .put("password", "secret"));

JWTAuth authProvider = JWTAuth.create(vertx, authConfig);

router.route("/protected/*").handler(JWTAuthHandler.create(authProvider));

router.route("/protected/somepage").handler(ctx -> {
  // some handle code...
});
JWT可以添加你需要的信息,服务器不存储状态,你将不需要集群会话。
JsonObject authConfig = new JsonObject().put("keyStore", new JsonObject()
  .put("type", "jceks")
  .put("path", "keystore.jceks")
  .put("password", "secret"));

JWTAuth authProvider = JWTAuth.create(vertx, authConfig);

authProvider.generateToken(new JsonObject().put("sub", "paulo").put("someKey", "some value"), new JWTOptions());

获取添加的信息

Handler<RoutingContext> handler = rc -> {
  String theSubject = rc.user().principal().getString("sub");
  String someKey = rc.user().principal().getString("someKey");
};

配置需要的权限

例如

AuthHandler listProductsAuthHandler = RedirectAuthHandler.create(authProvider);
listProductsAuthHandler.addAuthority("list_products");

// Need "list_products" authority to list products
router.route("/listproducts/*").handler(listProductsAuthHandler);

AuthHandler settingsAuthHandler = RedirectAuthHandler.create(authProvider);
settingsAuthHandler.addAuthority("role:admin");

// Only "admin" has access to /private/settings
router.route("/private/settings/*").handler(settingsAuthHandler);

链接多个auth处理程序

知道某些处理程序需要特定的提供程序非常重要,例如:

因此,预计供应商将不会在所有处理程序中共享。有些情况下可以在处理程序中共享提供程序,例如:

所以说,你要创建一个接受两个应用程序HTTP Basic AuthenticationForm Redirect你会开始配置你的链:


ChainAuthHandler chain = ChainAuthHandler.create();

// add http basic auth handler to the chain
chain.append(BasicAuthHandler.create(provider));
// add form redirect auth handler to the chain
chain.append(RedirectAuthHandler.create(provider));

// secure your route
router.route("/secure/resource").handler(chain);
// your app
router.route("/secure/resource").handler(ctx -> {
  // do something...
});

因此,当用户发出没有Authorization标头的请求时,这意味着链将无法通过基本身份验证处理程序进行身份验证,并尝试使用重定向处理程序进行身份验证。由于重定向处理程序总是重定向,因此您将被发送到您在该处理程序中配置的登录表单。

与vertx-web中的正常路由一样,auth chaning是一个序列,因此如果您希望回退到您的浏览器,并使用HTTP基本身份验证请求用户凭据而不是重定向,则需要的所有操作都是反向追加到连锁,链条。

现在假设您在提供Authorization的标题处发出请求Basic [token]在这种情况下,基本身份验证处理程序将尝试进行身份验证,如果成功,则链将停止并且vertx-web将继续处理您的处理程序。如果令牌无效,例如错误的用户名/密码,则该链接将继续到以下条目。在这个特定情况下,重定向认证处理程序。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值