Skip to content

Commit

Permalink
Add scope check function
Browse files Browse the repository at this point in the history
  • Loading branch information
XVincentX committed Jun 26, 2018
1 parent a3d53cf commit 9894cc4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
28 changes: 22 additions & 6 deletions lib/policies/oauth2-introspect/oauth2-introspect.js
Expand Up @@ -7,15 +7,31 @@ module.exports = function (actionParams) {
const scannedTokens = [];
const tokenIntrospection = tokenIntrospectionGenerator(actionParams);

passport.use('bearer-introspect', new BearerStrategy((accessToken, done) => {
passport.use('bearer-introspect', new BearerStrategy({ passReqToCallback: true }, (req, accessToken, done) => {
const requestedScopes = req.egContext.apiEndpoint.scopes;

const scopeCheck = (tokenData, done) => {
const avaiableScopes = tokenData.scopes ? tokenData.scopes.split(' ') : [];

if (!requestedScopes.some(requestedScope => {
if (!avaiableScopes.includes(requestedScope)) {
done(null, false);
return true;
}
})) {
return done(null, tokenData);
}
};

if (scannedTokens[accessToken] && ((Date.now() - scannedTokens[accessToken].lastCheck) / 1000) < actionParams.ttl) {
return done(null, scannedTokens[accessToken].data);
return scopeCheck(scannedTokens[accessToken].tokenData, done);
}

return tokenIntrospection(accessToken, 'access_token')
.then(data => {
scannedTokens[accessToken] = { lastCheck: Date.now(), data };
return done(null, data);
tokenIntrospection(accessToken, 'access_token')
.then(tokenData => {
scannedTokens[accessToken] = { lastCheck: Date.now(), tokenData };

return scopeCheck(tokenData, done);
})
.catch(() => { done(null, false); });
}));
Expand Down
38 changes: 28 additions & 10 deletions test/policies/oauth2-introspection/oauth2-introspection.js
Expand Up @@ -23,7 +23,8 @@ const gatewayConfig = (backendPort, introspectionPort) => ({
},
apiEndpoints: {
authorizedEndpoint: {
host: '*'
host: '*',
scopes: ['read', 'write']
}
},
policies: ['oauth2-introspect', 'proxy'],
Expand Down Expand Up @@ -51,16 +52,26 @@ describe('oAuth2 Introspection Policy', () => {
.then(([port, introspectionPort]) => {
config.gatewayConfig = gatewayConfig(port, introspectionPort);
const app = express();

const returnToken = sinon
.stub()
.onFirstCall().callsFake(res => {
res.json({ active: true });
})
.callsFake(res => {
res.json({ active: true, scopes: 'read write' });
});

introspectEndpointSpy = sinon.spy((req, res) => {
if (req.header('authorization') !== 'YXBpMTpzZWNyZXQ=') {
return res.sendStatus(401);
}

if (req.body.token !== 'example_token_value') {
if (!['token_value_1', 'token_value_2'].includes(req.body.token)) {
return res.json({ active: false });
}

return res.json({ active: true });
returnToken(res);
});
app.post('/introspect', express.urlencoded({ extended: true }), introspectEndpointSpy);
return new Promise((resolve, reject) => {
Expand All @@ -73,40 +84,47 @@ describe('oAuth2 Introspection Policy', () => {
.then(() => testHelper.setup()).then(({ app }) => { gateway = app; });
});

it('should return 401 when invalid authorization value is provided', () =>
it('should return 401 when no token is provided', () =>
request(gateway)
.get('/')
.expect(401)
);

it('should return 401 when invalid token is provided', () =>
it('should return 401 when an invalid token is sent', () =>
request(gateway)
.get('/')
.set('Authorization', `Bearer nasino`)
.expect(401)
);

it('should return 200 when valid token and authvalue are provided', () =>
it('should return 401 when a valid token is sent, but not sufficient scopes', () =>
request(gateway)
.get('/')
.set('Authorization', `Bearer token_value_1`)
.expect(401)
);

it('should return 200 when valid token and sufficient scopes are provided', () =>
request(gateway)
.get('/')
.set('Authorization', `Bearer example_token_value`)
.set('Authorization', `Bearer token_value_2`)
.expect(200)
);

it('should not call the introspection endpoint again because the token is valid already', () =>
request(gateway)
.get('/')
.set('Authorization', `Bearer example_token_value`)
.set('Authorization', `Bearer token_value_2`)
.expect(200)
.then(() => should(introspectEndpointSpy.callCount).equal(2))
.then(() => should(introspectEndpointSpy.callCount).equal(3))
);

it('should call the introspection endpoint again because a different token is sent', () =>
request(gateway)
.get('/')
.set('Authorization', `Bearer hola`)
.expect(401)
.then(() => should(introspectEndpointSpy.callCount).equal(3))
.then(() => should(introspectEndpointSpy.callCount).equal(4))
);

after('cleanup', (done) => {
Expand Down

0 comments on commit 9894cc4

Please sign in to comment.