Custom callback and user profile URLs for OAuth2
For parsing `oauth2_UsernameField` values like `profile.preferred_username`, this makes use of `eval()` which is generally Evil™, but I'm assuming that anyone with permission to edit config.json likely has permission to make changes to the fedwiki source code already anyway, so it's fragile rather than increasing a security attack surface. An alternative would be using a small function to look up properties of the `params` / `profile` objects using the same dotted-path notation.
This commit is contained in:
parent
f4f44afa35
commit
001def2fea
|
@ -1,4 +1,36 @@
|
|||
## Generic OAuth 2
|
||||
|
||||
### Login provider set-up
|
||||
|
||||
Like the other PassportJS login providers, we'll need a separate "OAuth2 Client"
|
||||
(others call it an "app", a "product" etc.) for our Federated Wiki instance.
|
||||
|
||||
How to do this varies slightly for each provider.
|
||||
|
||||
### `config.json`
|
||||
|
||||
In general, you will need to specify:
|
||||
* `oauth2_clientID` -- some systems generate this for you, others allow you to
|
||||
specify it
|
||||
* `oauth2_clientSecret` -- secure key (keep this secret!)
|
||||
* `oauth2_AuthorizationURL` and `oauth2_TokenURL` -- from your login provider's documentation
|
||||
|
||||
You will also need to specify a callback URL. For some providers, you can add
|
||||
this when making a new "OAuth Client" for your wiki, for others you will need to
|
||||
specify it with `oauth2_CallbackURL`.
|
||||
|
||||
You might also need to tell Federated Wiki how to look up usernames:
|
||||
* `oauth2_UserInfoURL` -- from login provider's documentation
|
||||
* `oauth2_UsernameField` -- starting with
|
||||
* `params` for information returned in the original token request, or
|
||||
* `profile` for data returned from `oauth2_UserInfoURL`, if you provided it.
|
||||
|
||||
Sometimes, you'll be able to look up the URLs by visiting your provider's
|
||||
`/.well-known/openid-configuration` URL in a web browser.
|
||||
|
||||
### Examples
|
||||
|
||||
#### Nextcloud
|
||||
|
||||
```JSON
|
||||
{
|
||||
|
@ -8,8 +40,21 @@
|
|||
"oauth2_clientSecret": "CLIENT SECRET",
|
||||
"oauth2_AuthorizationURL": "https://auth.example.com/oauth2/authorize",
|
||||
"oauth2_TokenURL": "https://auth.example.com/oauth2/token",
|
||||
"wikiDomains": {
|
||||
"example.wiki": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Keycloak
|
||||
|
||||
```JSON
|
||||
{
|
||||
"farm": true,
|
||||
"security_type": "passportjs",
|
||||
"oauth2_clientID": "CLIENT ID",
|
||||
"oauth2_clientSecret": "CLIENT SECRET",
|
||||
"oauth2_AuthorizationURL": "https://auth.example.com/auth/realms/Wiki.Cafe/protocol/openid-connect/auth",
|
||||
"oauth2_TokenURL": "https://auth.example.com/auth/realms/Wiki.Cafe/protocol/openid-connect/token",
|
||||
"oauth2_UserInfoURL": "https://auth.example.com/auth/realms/Wiki.Cafe/protocol/openid-connect/userinfo",
|
||||
"oauth2_CallbackURL": "http://localhost:3000/auth/oauth2/callback",
|
||||
"oauth2_UsernameField": "profile.preferred_username"
|
||||
}
|
||||
```
|
||||
|
|
|
@ -201,23 +201,42 @@ module.exports = exports = (log, loga, argv) ->
|
|||
|
||||
oauth2StrategyName = callbackHost + 'OAuth'
|
||||
|
||||
if argv.oauth2_UserInfoURL?
|
||||
OAuth2Strategy::userProfile = (accesstoken, done) ->
|
||||
console.log "hello"
|
||||
console.log accesstoken
|
||||
@_oauth2._request "GET", argv.oauth2_UserInfoURL, null, null, accesstoken, (err, data) ->
|
||||
if err
|
||||
return done err
|
||||
try
|
||||
data = JSON.parse data
|
||||
catch e
|
||||
return done e
|
||||
done(null, data)
|
||||
|
||||
passport.use(oauth2StrategyName, new OAuth2Strategy({
|
||||
clientID: argv.oauth2_clientID
|
||||
clientSecret: argv.oauth2_clientSecret
|
||||
authorizationURL: argv.oauth2_AuthorizationURL
|
||||
tokenURL: argv.oauth2_TokenURL
|
||||
# userURL: argv.oauth2_UserURL
|
||||
# scope: 'user:emails'
|
||||
# callbackURL is optional, and if it exists must match that given in
|
||||
# the OAuth application settings - so we don't specify it.
|
||||
tokenURL: argv.oauth2_TokenURL,
|
||||
# not all providers have a way of specifying the callback URL
|
||||
callbackURL: argv.oauth2_CallbackURL,
|
||||
userInfoURL: argv.oauth2_UserInfoURL
|
||||
}, (accessToken, refreshToken, params, profile, cb) ->
|
||||
console.log("accessToken", accessToken)
|
||||
console.log("refreshToken", refreshToken)
|
||||
console.log("params", params)
|
||||
console.log("profile", profile)
|
||||
if argv.oauth2_UsernameField?
|
||||
username_query = argv.oauth2_UsernameField
|
||||
else
|
||||
username_query = 'params.user_id'
|
||||
user.oauth2 = {
|
||||
id: params.user_id,
|
||||
username: params.user_id,
|
||||
displayName: params.user_id,
|
||||
id: eval username_query,
|
||||
username: eval username_query
|
||||
displayName: eval username_query
|
||||
}
|
||||
console.log user.oauth2
|
||||
cb(null, user)))
|
||||
|
||||
# Github Strategy
|
||||
|
|
Loading…
Reference in New Issue