首页 > 解决方案 > 在spring-boot中使用Outh服务器uri验证nodejs资源服务器中的访问令牌

问题描述

  1. 我有 OAuth2 服务器[Spring-boot],它使用密码凭据方法验证客户端。
  2. 前端客户端[Vuejs]获取的访问令牌使用令牌访问资源服务器[Spring-boot]。
  3. 在这里,虽然访问令牌由前端客户端传递给资源服务器,但资源服务器使用以下代码与 OAuth2 服务器交叉验证它

    @Configuration @EnableResourceServer public class OAuth2ResourceServerConfigRemoteTokenService extends ResourceServerConfigurerAdapter { @Primary @Bean public RemoteTokenServices tokenServices() { final RemoteTokenServices tokenService = new RemoteTokenServices(); tokenService.setCheckTokenEndpointUrl("https://localhost:9088/oauth/check_token"); tokenService.setClientId("fooClientIdPassword"); tokenService.setClientSecret("password"); return tokenService; } }

  4. 现在,我正在尝试用 nodejs 实现相同的功能,因为我计划拆分一个特定的功能,这会对用 spring-boot 编写的资源服务器产生开销。

  5. 我不知道如何在nodejs中实现交叉验证机制,如下面的代码。

tokenService.setCheckTokenEndpointUrl("https://localhost:9088/oauth/check_token");

标签: node.jsspring-bootoauth-2.0

解决方案


尝试 express-oauth2-bearer 库,它工作正常首先安装它: npm i express-oauth2-bearer --save 并在您的客户端中使用此代码:该库需要以下值来授权请求​​:

  • Issuer Base URL:授权服务器的基本 URL。如果您使用的是 Auth0,这是您的租户域,在Auth0 仪表板中您的应用程序的“设置”选项卡上以https://(like https://tenant.auth0.com)为前缀。
  • Allowed Audiences:访问令牌允许的受众标识符(或以逗号分隔的多个)。如果您使用的是 Auth0,这是在Auth0 仪表板的 API的设置选项卡上找到的标识符

这些可以在.env应用程序根目录的文件中配置:

# .env

ISSUER_BASE_URL=https://YOUR_DOMAIN
ALLOWED_AUDIENCES=https://api.yourapplication.com

...或在您的应用程序代码中:

app.use(auth({
  issuerBaseURL: 'https://tenant.auth0.com',
  allowedAudiences: 'https://api.yourapplication.com'
}));

OpenID 策略是令牌验证的默认策略。使用文件中设置的配置值.env,以下代码会将对所有正在进行的路由的请求限制为具有与https://api.yourapplication.com受众和read:products范围的有效访问令牌的路由:

const { auth, requiredScopes } = require('express-oauth2-bearer');

app.use(auth());

app.get('/products',
  requiredScopes('read:products'),
  (req, res) => {
    console.dir(req.auth.claims);
    res.sendStatus(200);
  });

如果访问令牌预计不会像 OpenID Connect ID 令牌那样被签名,请添加auth带有回调的中间件以进行验证,如下所示:

const { auth, requiredScopes } = require('express-oauth2-bearer');

const validateAccesToken = async (token) => {
  const token = await db.tokens.find(token);
  if (token.expired) { return; }
  return token;
};

app.use(auth(validateAcessToken)));

app.get('/products',
  requiredScopes('read:products'),
  (req, res) => {
    console.dir(req.auth.claims);
    res.sendStatus(200);
  });

推荐阅读