restricted saving keys to the issuer only
This commit is contained in:
		
							parent
							
								
									f260b5afc0
								
							
						
					
					
						commit
						faea77bd10
					
				
							
								
								
									
										88
									
								
								rest.js
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								rest.js
									
									
									
									
									
								
							@ -20,6 +20,46 @@ module.exports.create = function (bigconf, deps, app) {
 | 
			
		||||
    next();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  function authorizeIssuer(req, res, next) {
 | 
			
		||||
    var promise = PromiseA.resolve().then(function () {
 | 
			
		||||
      // It might seem unnecessary to wrap a promise in another promise, but this way it will
 | 
			
		||||
      // catch the error thrown when a token isn't provided and verifyAsync isn't a function.
 | 
			
		||||
      return req.oauth3.verifyAsync();
 | 
			
		||||
    }).then(function (token) {
 | 
			
		||||
      // Now that we've confirmed the token is valid we also need to make sure the authorized party
 | 
			
		||||
      // is us.
 | 
			
		||||
      // TODO: For the time being the only verify-able tokens are the ones we issued, but this
 | 
			
		||||
      // will not always be the case. We will need a better way to verify the authorized party.
 | 
			
		||||
      if (token.iss !== token.azp || token.iss !== token.aud) {
 | 
			
		||||
        throw new Error("token does not allow access to requested resource");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var sub = token.sub || token.ppid || (token.acx && (token.acx.id || token.acx.appScopedId));
 | 
			
		||||
      if (!sub) {
 | 
			
		||||
        if (!Array.isArray(token.axs) || !token.axs.length) {
 | 
			
		||||
          throw new Error("no account pairwise identifier");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var allowed = token.axs.some(function (acc) {
 | 
			
		||||
          return req.params.sub === (acc.id || acc.ppid || acc.appScopedId);
 | 
			
		||||
        });
 | 
			
		||||
        if (!allowed) {
 | 
			
		||||
          throw new Error("no account pairwise identifier matching '" + req.params.sub + "'");
 | 
			
		||||
        }
 | 
			
		||||
        sub = req.params.sub;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (req.params.sub !== sub) {
 | 
			
		||||
        throw new Error("token does not allow access to resources for '"+req.params.sub+"'");
 | 
			
		||||
      }
 | 
			
		||||
      next();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    app.handleRejection(req, res, promise, '[issuer@oauth3.org] authorize req as issuer');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Jwks.thumbprint = function (jwk) {
 | 
			
		||||
    // To produce a thumbprint we need to create a JSON string with only the required keys for
 | 
			
		||||
    // the key type, with the keys sorted lexicographically and no white space. We then need
 | 
			
		||||
@ -88,44 +128,12 @@ module.exports.create = function (bigconf, deps, app) {
 | 
			
		||||
      return { success: true };
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    app.handlePromise(req, res, promise, "[issuer@oauth3.org] create JWK");
 | 
			
		||||
    app.handlePromise(req, res, promise, "[issuer@oauth3.org] save JWK");
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Grants.authorizeReq = function (req) {
 | 
			
		||||
    return PromiseA.resolve().then(function () {
 | 
			
		||||
      // It might seem unnecessary to wrap a promise in another promise, but this way it will
 | 
			
		||||
      // catch the error thrown when a token isn't found and verifyAsync isn't a function.
 | 
			
		||||
      return req.oauth3.verifyAsync();
 | 
			
		||||
    }).then(function (token) {
 | 
			
		||||
      // Just because the token is valid doesn't mean the token is authorized to get or save grants.
 | 
			
		||||
      // The only place that should be allowed to access grants on behalf of the user is the issuer.
 | 
			
		||||
      if (token.iss !== token.azp) {
 | 
			
		||||
        throw new Error("token does not allow access to grants");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var sub = token.sub || token.ppid || (token.acx && (token.acx.id || token.acx.appScopedId));
 | 
			
		||||
      if (!sub) {
 | 
			
		||||
        if (!Array.isArray(token.axs) || !token.axs.length) {
 | 
			
		||||
          throw new Error("no account pairwise identifier");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var allowed = token.axs.some(function (acc) {
 | 
			
		||||
          return req.params.sub === (acc.id || acc.ppid || acc.appScopedId);
 | 
			
		||||
        });
 | 
			
		||||
        if (!allowed) {
 | 
			
		||||
          throw new Error("no account pairwise identifier matching '" + req.params.sub + "'");
 | 
			
		||||
        }
 | 
			
		||||
        sub = req.params.sub;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return sub;
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Grants.restful.getOne = function (req, res) {
 | 
			
		||||
    var promise = Grants.authorizeReq(req).then(function (sub) {
 | 
			
		||||
      return req.Store.get(sub+'/'+req.params.azp);
 | 
			
		||||
    }).then(function (grant) {
 | 
			
		||||
    var promise = req.Store.get(req.params.sub+'/'+req.params.azp).then(function (grant) {
 | 
			
		||||
      if (!grant) {
 | 
			
		||||
        throw new Error('no grants found');
 | 
			
		||||
      }
 | 
			
		||||
@ -140,9 +148,7 @@ module.exports.create = function (bigconf, deps, app) {
 | 
			
		||||
    app.handlePromise(req, res, promise, "[issuer@oauth3.org] retrieve grants");
 | 
			
		||||
  };
 | 
			
		||||
  Grants.restful.getAll = function (req, res) {
 | 
			
		||||
    var promise = Grants.authorizeReq(req).then(function (sub) {
 | 
			
		||||
      return req.Store.find({ sub: sub });
 | 
			
		||||
    }).then(function (results) {
 | 
			
		||||
    var promise = req.Store.find({ sub: req.params.sub }).then(function (results) {
 | 
			
		||||
      return results.map(function (grant) {
 | 
			
		||||
        return {
 | 
			
		||||
          sub:   grant.sub,
 | 
			
		||||
@ -158,14 +164,14 @@ module.exports.create = function (bigconf, deps, app) {
 | 
			
		||||
    app.handlePromise(req, res, promise, "[issuer@oauth3.org] retrieve grants");
 | 
			
		||||
  };
 | 
			
		||||
  Grants.restful.saveNew = function (req, res) {
 | 
			
		||||
    var promise = Grants.authorizeReq(req).then(function (sub) {
 | 
			
		||||
    var promise = PromiseA.resolve().then(function () {
 | 
			
		||||
      if (typeof req.body.scope !== 'string') {
 | 
			
		||||
        throw new Error("malformed request: 'scope' should be a string");
 | 
			
		||||
      }
 | 
			
		||||
      var scope = req.body.scope.split(/[+ ,]+/g).join(',');
 | 
			
		||||
 | 
			
		||||
      var grant = {
 | 
			
		||||
        sub:   sub,
 | 
			
		||||
        sub:   req.params.sub,
 | 
			
		||||
        azp:   req.params.azp,
 | 
			
		||||
        scope: scope,
 | 
			
		||||
      };
 | 
			
		||||
@ -179,9 +185,11 @@ module.exports.create = function (bigconf, deps, app) {
 | 
			
		||||
 | 
			
		||||
  app.use(   '/jwks', attachSiteStore.bind(null, 'IssuerOauth3OrgJwks'));
 | 
			
		||||
  app.get(   '/jwks/:kid.json', Jwks.restful.get);
 | 
			
		||||
  app.use(   '/jwks/:sub', authorizeIssuer); // Everything but getting keys is only for the issuer
 | 
			
		||||
  app.post(  '/jwks/:sub', Jwks.restful.saveNew);
 | 
			
		||||
 | 
			
		||||
  app.use(   '/grants', attachSiteStore.bind(null, 'IssuerOauth3OrgGrants'));
 | 
			
		||||
  // Everything regarding grants is only for the issuer
 | 
			
		||||
  app.use(   '/grants/:sub', authorizeIssuer, attachSiteStore.bind(null, 'IssuerOauth3OrgGrants'));
 | 
			
		||||
  app.get(   '/grants/:sub', Grants.restful.getAll);
 | 
			
		||||
  app.get(   '/grants/:sub/:azp', Grants.restful.getOne);
 | 
			
		||||
  app.post(  '/grants/:sub/:azp', Grants.restful.saveNew);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user