范围错误不足。令牌不包含范围

时间:2018-08-15 04:34:25

标签: jwt auth0 scopes

在我的应用程序中,每个管理员都具有app_metdata属性,该属性定义他们是否具有管理员角色。如果用户具有此元数据,我将使用以下规则添加管理范围,但是使用令牌的任何API调用都会返回不足的范围错误。我已使用jwt.io验证令牌中没有返回任何作用域。要确保我的授权范围包含在JWT中,我该怎么做?

function (user, context, callback) {
     var _ = require("lodash"); 
     var req = context.request;  
     var scopes = (req.query && req.query.scope) || (req.body && 
     req.body.scope);

     // Normalize scopes into an array
     scopes = (scopes && scopes.split(" ")) || '';


     if (user.app_metadata !== undefined && user.app_metadata.roles !== 
     undefined && user.app_metadata.roles.indexOf('admin') >= 0) {
     scopes.push("admin"); 
     }
     // Restrict the access token scopes according to the current user
     //context.accessToken.scope = restrictScopes(user, scopes);
    console.log('scopes',scopes.join(" "));
    context.accessToken.scope = scopes.join(" ");
    callback(null, user, context);
}

1 个答案:

答案 0 :(得分:1)

规则看起来正确。但是问题可能出在loadash上。我使用授权扩展来向用户添加角色,权限和组。它更新用户app_metadata字段。为了在范围内添加用户的权限,我使用了以下规则。

function (user, context, callback) {
  if (context.request.query.audience === '[api identifier]' && 
      context.clientID === '[client id]') {
  var req = context.request;
  var scopes = (req.query && req.query.scope) || (req.body && req.body.scope);
  var permissions = user.permissions || [];
  var requestedScopes = context.request.body.scope || context.request.query.scope;
  var filteredScopes = requestedScopes.split(' ').filter( function(x) {
    return x.indexOf(':') < 0;
  });
  Array.prototype.push.apply(filteredScopes, permissions);
  console.log(filteredScopes.join(' '));
  context.accessToken.scope = filteredScopes.join(' ');
  }
  callback(null, user, context);
} 

https://auth0.com/docs/architecture-scenarios/spa-api/part-2#configure-the-authorization-extension

确保将权限限制为特定的API和客户端。否则,您可能会错误地提供对令牌中管理API的访问。如果未使用授权扩展,则可以从用户对象(user_metadata)获得正确的权限。

或者,要在令牌中添加任何特定的API scope来进行API访问,则可以在调用/oauth/token/authorize端点时请求范围。

/authorize端点用于implicit grantauthorization code grant flowauthorization code grant with PKCE。该调用的目的是获得用户的同意,以代表用户调用API(在受众字段中指定)并做某些事情(在范围内指定)。 Auth0将对用户进行身份验证并获得同意,除非事先已同意。如果您更改范围的值,则需要再次同意Auth0。应该在浏览器中执行

https://YOUR_AUTH0_DOMAIN/authorize?
  audience=API_IDENTIFIER&
  scope=openid%20email%20profile%20read:user&
  response_type=token%20id_token&
  client_id=YOUR_CLIENT_ID&
  redirect_uri=https://YOUR_APP/callback&
  state=123&
  nonce=234

另一方面,/ oauth / token端点用于实现clent credentials grantresource owner password credentials授予。以下curl命令要求提供令牌。它正在使用Resouce所有者密码凭据授予

curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN/oauth/token' \
  --header 'content-type: application/json' \
  --data '{"grant_type":"password","username": "user@example.com","password": "pwd","audience": "https://someapi.com/api", "scope": "read:sample", "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET"}'

注意:您必须使用Access令牌进行API调用。

附加性,您可以尝试使用访问令牌或id_token中的规则将管理员角色或权限添加为自定义声明。根据声明,您可以限制访问。例如,

function (user, context, callback) {
  const namespace = 'https://myapi.com/';
  context.idToken[namespace + 'user_metadata'] = user.user_metadata;
  context.accessToken[namespace + 'user_metadata'] = user.user_metadata;

  callback(null, user, context);
}
相关问题