Merge pull request #179 from mozilla/175-oidc-userinfo
feat(openid): make /v1/profile act as the OIDC UserInfo endpoint
This commit is contained in:
Коммит
d2bbf6939b
12
docs/API.md
12
docs/API.md
|
@ -88,6 +88,18 @@ curl -v \
|
|||
}
|
||||
```
|
||||
|
||||
#### OpenID Connect UserInfo Endpoint
|
||||
|
||||
Per the [OpenID Connect Core
|
||||
spec](http://openid.net/specs/openid-connect-core-1_0.html#UserInfo),
|
||||
this endpoint also acts as the "UserInfo" endpoint. Any requests with a
|
||||
token that include the `openid` scope will include the `sub` claim, an
|
||||
alias to the `uid`.
|
||||
|
||||
Additional scopes supported for OpenID Connect:
|
||||
|
||||
- `email`
|
||||
|
||||
### GET /v1/email
|
||||
|
||||
- scope: `profile:email`
|
||||
|
|
|
@ -14,7 +14,7 @@ const AUTH_SERVER_URL = config.get('authServer.url') + '/account/profile';
|
|||
module.exports = {
|
||||
auth: {
|
||||
strategy: 'oauth',
|
||||
scope: ['profile', 'profile:email']
|
||||
scope: ['profile', 'profile:email', /* openid-connect scope */'email' ]
|
||||
},
|
||||
response: {
|
||||
schema: {
|
||||
|
|
|
@ -8,11 +8,12 @@ const checksum = require('checksum');
|
|||
|
||||
const batch = require('../batch');
|
||||
|
||||
function hasProfileScope(scopes) {
|
||||
function hasAllowedScope(scopes) {
|
||||
for (var i = 0, len = scopes.length; i < len; i++) {
|
||||
var scope = scopes[i];
|
||||
// careful to not match a scope of 'profilebogie'
|
||||
if (scope === 'profile' || scope.indexOf('profile:') === 0) {
|
||||
if (scope === 'profile' || scope === 'email'
|
||||
|| scope.indexOf('profile:') === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -35,11 +36,15 @@ module.exports = {
|
|||
email: Joi.string().allow(null),
|
||||
uid: Joi.string().allow(null),
|
||||
avatar: Joi.string().allow(null),
|
||||
displayName: Joi.string().allow(null)
|
||||
displayName: Joi.string().allow(null),
|
||||
|
||||
//openid-connect
|
||||
sub: Joi.string().allow(null)
|
||||
}
|
||||
},
|
||||
handler: function email(req, reply) {
|
||||
if (!hasProfileScope(req.auth.credentials.scope || [])) {
|
||||
var creds = req.auth.credentials;
|
||||
if (!hasAllowedScope(creds.scope || [])) {
|
||||
return reply(Boom.forbidden());
|
||||
}
|
||||
batch(req, {
|
||||
|
@ -49,6 +54,9 @@ module.exports = {
|
|||
displayName: '/v1/display_name'
|
||||
})
|
||||
.done(function (result) {
|
||||
if (creds.scope.indexOf('openid') !== -1) {
|
||||
result.sub = creds.user;
|
||||
}
|
||||
var rep = reply(result);
|
||||
var etag = computeEtag(result);
|
||||
if (etag) {
|
||||
|
|
21
test/api.js
21
test/api.js
|
@ -318,6 +318,27 @@ describe('/profile', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should support openid-connect "email" scope', function() {
|
||||
mock.token({
|
||||
user: USERID,
|
||||
scope: ['openid', 'email']
|
||||
});
|
||||
mock.email('user@example.domain');
|
||||
return Server.api.get({
|
||||
url: '/profile',
|
||||
headers: {
|
||||
authorization: 'Bearer ' + tok
|
||||
}
|
||||
}).then(function(res) {
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert.equal(res.result.email, 'user@example.domain');
|
||||
assert.equal(res.result.sub, USERID);
|
||||
assert.equal(Object.keys(res.result).length, 2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('/email', function() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче