-
Notifications
You must be signed in to change notification settings - Fork 17
Upgrade process from 3.1.6 to 4.0
Note: This is a draft doc. It's not complete neither accurate
These doc describes the steps to mutate a passport 3.1.6 into a 4.0 one:
Previous (3.1.x) property | Becomes in 4.x |
---|---|
passportConfigAPI | configurationEndpoint |
applicationStartpoint | failureRedirectUrl |
The following remain the same: logLevel, clientId, keyPath, keyId, keyAlg
Some properties of 3.1.x file were moved to LDAP. See conf below
As an example, this is how passport-config.json looks now:
{
"configurationEndpoint": "https://my.gluu.host/identity/restv1/passport/config",
"failureRedirectUrl": "https://my.gluu.host/oxauth/auth/passport/passportlogin.htm",
"logLevel": "debug",
"clientId": "@!D709.DD63.C2A5.9C6A!0001!2533.B35B!0008!B37C.2DF3",
"keyPath": "/etc/certs/passport-rp.pem",
"keyId": "890dc947-f5ab-476a-bba2-4ae8f297672d",
"keyAlg": "RS512"
}
The contents will end up imported under ou=oxpassport,ou=configuration,inum=...,ou=appliances,o=gluu
(attribute gluuPassportConfiguration
)
For reference, this is how a typical content looks like.
So based on the template, generate the 3 sections:
For the logging section, use for level
and consoleLogOnly
the values already in passport-config.json (3.1.x)
For activeMQConf
section, use the same values found under activeMQConf
in passport-config.json (3.1.x), except for:
-
port
: This is expected to be an integer (not a string as in 3.1.x). If conversion fails, simply set it to zero -
isEnabled
which is now simply calledenabled
for 4.x
For every key (section) found in in /etc/gluu/conf/passport-inbound-idp-initiated.json create an item inside authorizationParams
filling values as follows:
Property | Value |
---|---|
provider | The key value (e.g. "your_idp_name") |
redirect_uri | redirect_uri value |
response_type | response_type value |
scope | take scope value (it's an array) and convert it into a space-separated string |
Account that if in passport-inbound-idp-initiated.json any of client_id or redirect_uri is empty, then the item in authorizationParams
should be empty.
For clientId use the client_id
of the first occurrence of openidclient
found passport-inbound-idp-initiated.json. However, if this value is empty, use the inum of the idp-initiated client generated at the beginning.
Examples:
-
If passport-inbound-idp-initiated.json is this (the default one), then the resulting
idpInitiated
section should look like:{ "openidclient": { "authorizationEndpoint": "https://my.gluu.host/oxauth/restv1/authorize", "clientId": "@!....", "acrValues": "passport_saml" }, "authorizationParams": [] }
-
If passport-inbound-idp-initiated.json is
{ "your_idp_name_1": { "openidclient": { "server_uri": "something", "client_id": "client_id_1" }, "authorization_params": { "client_id": "client_id_1A", "redirect_uri": "redirect_uri_1", "acr_values": "acr1", "response_type": "code", "scope": ["openid", "user_name", "email"] } }, "your_idp_name_2": { "openidclient": { "server_uri": "something2", "client_id": "client_id_2" }, "authorization_params": { "client_id": "client_id_2A", "redirect_uri": "redirect_uri_2", "acr_values": "acr2", "response_type": "code token", "scope": ["openid"] } } }
the result should be:
{ "openidclient": { "authorizationEndpoint": "https://my.gluu.host/oxauth/restv1/authorize", "clientId": "client_id_1", "acrValues": "passport_saml" }, "authorizationParams": [ { "provider" : "your_idp_name_1", "redirect_uri": "redirect_uri_1", "response_type": "code", "scope": "openid user_name email" }, { "provider" : "your_idp_name_2", "redirect_uri": "redirect_uri_2", "response_type": "code token", "scope": "openid" } ] }
In 3.1.x the providers information is found in 2 places: LDAP and passport-saml-config.json. LDAP has info about oauth-based providers, while the file has info about SAML providers.
For every attribute gluuPassportConfiguration
under ou=oxpassport,ou=configuration,inum=...,ou=appliances,o=gluu
create an item inside providers
the following way:
Property | Value |
---|---|
id | Use the value of strategy field |
displayName | Use the value of strategy field |
type | Use "oauth" if strategy is any of dropbox, facebook, github, google, linkedin, openidconnect, tumblr, twitter, windowslive, yahoo. Otherwise use "openidconnect" |
mapping | Use the value of strategy field if strategy is any of dropbox, facebook, github, google, linkedin, openidconnect, tumblr, twitter, windowslive, yahoo. Otherwise use "openidconnect-default" |
enabled | use true |
logo_img | Lookup value2 where value1 is "logo_img" inside fieldset. If not found, do not set this property |
requestForEmail | Lookup value2 where value1 is "requestForEmail" inside fieldset. If it equals the string "true", use true (as boolean). Otherwise, do not set this property |
emailLinkingSafe | Lookup value2 where value1 is "emailLinkingSafe" inside fieldset. If it equals the string "true", use true (as boolean). Otherwise, do not set this property |
Fill property passportStrategyId
according to the following rules:
mapping value | Value for passportStrategyId |
---|---|
github | passport-github |
openidconnect-default | passport-openidconnect |
passport-twitter | |
yahoo | passport-yahoo-oauth2 |
tumblr | passport-tumblr |
passport-linkedin-oauth2 | |
passport-google-oauth2 | |
passport-facebook | |
dropbox | passport-dropbox-oauth2 |
windowslive | passport-windowslive |
Fill a dictionary named "options" the following way: for every field (in fieldset) use value1 for the key and value2 for value. Ignore fields when value1 is any of logo_img, requestForEmail, emailLinkingSafe.
Example. Suppose the following is in LDAP:
gluuPassportConfiguration: {"strategy": "myOP", "fieldset": [{"value1": "logo_img", "value2": "some_url"}, {"value1": "requestForEmail", "value2": "true"}, {"value1": "extraPropertyA", "value2": "AHA"}, {"value1": "extraPropertyB", "value2": "WTF"}]}
gluuPassportConfiguration: {"strategy": "google", "fieldset": [{"value1": "logo_img", "value2" : "img/gugol.png"}, {"value1": "clientID", "value2": "some_client_id"}, {"value1": "clientSecret", "value2": "some_client_secret"}]}
gluuPassportConfiguration: {"strategy": "github", "fieldset": [{"value1": "someProperty", "value2" : "Nothing"}]}
This should generate:
[
{
"id": "myOP",
"displayName": "myOP",
"type": "openidconnect",
"mapping" : "openidconnect-default",
"enabled": true,
"logo_img" : "some_url",
"requestForEmail": true,
"passportStrategyId": "passport-openidconnect",
"options": {
"extraPropertyA": "AHA",
"extraPropertyB": "WTF"
}
},
{
"id": "google",
"displayName": "google",
"type": "oauth",
"mapping" : "google",
"enabled": true,
"logo_img" : "img/gugol.png",
"passportStrategyId": "passport-google-oauth2",
"options": {
"clientID": "some_client_id",
"clientSecret": "some_client_secret"
}
},
{
"id": "github",
"displayName": "github",
"type": "oauth",
"mapping" : "github",
"enabled": true,
"passportStrategyId": "passport-github",
"options": {
"someProperty": "someProperty"
}
}
]
Beside the oauth providers, we also have to add the SAML ones to the providers
array.
So for every key in passport-saml-config.json we have to create an item this way:
Property | Value |
---|---|
id | Use key |
displayName | Use key |
type | Use "saml" |
enabled | Use propery enable from json file. Convert it to boolean beforehand |
logo_img | As stored in logo_img property of json file |
requestForEmail | As stored in requestForEmail property of json file. If absent, do not set this property |
emailLinkingSafe | As stored in emailLinkingSafe property of json file. If absent, do not set this property |
passportStrategyId | Use "passport-saml" |
mapping | Use key |
Fill a dictionary named "options" with all the subkeys present in reverseMapping and their corresponding values except for enable, logo_img, requestForEmail and emailLinkingSafe. All dictionary values must be stored as strings regardless of how they appear in the original passport-saml-config.json file.
Create a .js file under ~/temp/mappings with the name of the key. For instance, if the key is "My_Provider", a "My_Provider.js" can be created. Files created will be moved to its final destination afterwards
For generating files use this template:
module.exports = profile => {
return {
local_key_0: profile["remote_key_val_0"],
...
local_key_n: profile["remote_key_val_n"]
}
}
Where local_key_i
is the item at position i in generic_local_attributes_list
and remote_key_val_i
is the value of a key in reverseMapping so that such key has the same name than the i-th element in generic_remote_attributes_list
.
Remarks:
- Both
generic_remote_attributes_list
andgeneric_local_attributes_list
are comma-separated lists found in the configuration properties of thepassport-saml
script. - Both lists have the same length.
- If for a value i, the i-th element of
generic_remote_attributes_list
is "provider", ignore and continue with the next value of i. - If there is no match in the reverseMapping with respect to
generic_remote_attributes_list
, ignore and continue with the next value of i.
The above is better explained using an example. Assume the following parameterization of passport_saml
script:
...
oxConfigurationProperty: {"value1":"generic_remote_attributes_list","value2":"username, email, name, name, givenName, familyName, provider}
oxConfigurationProperty: {"value1":"generic_local_attributes_list" ,"value2":"uid, mail, cn, displayName, givenName, sn, provider"}
...
And assume the reverseMapping
in passport-saml-config has the following:
{
"email": "email",
"username": "urn:oid:0.9.2342.19200300.100.1.1",
"id": "urn:oid:0.9.2342.19200300.100.1.1",
"name": "urn:oid:2.5.4.42",
"givenName": "urn:oid:2.5.4.42",
"provider": "issuer"
}
local_key_0
is uid (the first element in the "local" list). To compute remote_key_val_0
, we pick the 0-th element in "remote", that is,
username and then search for it in the reverseMapping. The following is found "username": "urn:oid:0.9.2342.19200300.100.1.1"
so the value needed is "urn:oid:0.9.2342.19200300.100.1.1"
yielding:
uid: profile["urn:oid:0.9.2342.19200300.100.1.1"]
Following the same idea, for local_key_1
(mail), "email" is searched in the reverse mapping, thus yielding:
mail: profile["email"],
Note that local_key_5
is not generated since familyName is not part of reverse mapping. local_key_6
is not generated since the 6th key in the remote list is "provider".
Here it goes an example that sums up all of the previous section. Assume passport-saml-config.json has:
{
"your_idp_name1": {
"entryPoint": "https://idp1.example.com/idp/profile/SAML2/POST/SSO",
"issuer": "urn:test:example",
"identifierFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
"enable": "true",
"cert": "your_idp_public_certicate_in_single_line",
"reverseMapping": {
"username": "urn:oid:0.9.2342.19200300.100.1.1",
"name": "urn:oid:2.16.840.1.113730.3.1.241"
}
},
"your_idp_name2": {
"entryPoint": "entrypoint2",
"issuer": "urn:test",
"identifierFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
"enable":"false",
"cert":"the cert",
"acceptedClockSkewMs": 20000,
"reverseMapping": {
"email" : "email",
"username": "urn:oid:0.9.2342.19200300.100.1.1",
"members": "urn:1.3.6.1.4.1.48710.1.3.121",
"provider" :"issuer"
}
}
}
and passport_saml
script with:
...
oxConfigurationProperty: {"value1":"generic_remote_attributes_list","value2":"username, email, name, provider, members"}
oxConfigurationProperty: {"value1":"generic_local_attributes_list", "value2":"uid, mail, displayName, provider, memberOf"}
...
The providers generated will look like:
...
{
"id": "your_idp_name1",
"displayName": "your_idp_name1",
"type": "saml",
"enabled": true,
"passportStrategyId": "passport-saml",
"mapping": "your_idp_name1",
"options": {
"entryPoint": "https://idp1.example.com/idp/profile/SAML2/POST/SSO",
"issuer": "urn:test:example",
"identifierFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
"cert": "your_idp_public_certicate_in_single_line"
}
},
{
"id": "your_idp_name2",
"displayName": "your_idp_name2",
"type": "saml",
"enabled": false,
"passportStrategyId": "passport-saml",
"mapping": "your_idp_name2",
"options": {
"entryPoint": "entrypoint2",
"issuer": "urn:test",
"identifierFormat": "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
"cert": "the cert",
"acceptedClockSkewMs": "20000"
}
}
And the following files must have been created in directory ~/temp/mappings
:
your_idp_name1.json
:
module.exports = profile => {
return {
uid: profile["urn:oid:0.9.2342.19200300.100.1.1"],
displayName: profile["urn:oid:2.16.840.1.113730.3.1.241"]
}
}
your_idp_name2.json
:
module.exports = profile => {
return {
uid: profile["urn:oid:0.9.2342.19200300.100.1.1"],
mail: profile["email"],
memberOf: profile["urn:1.3.6.1.4.1.48710.1.3.121"]
}
}
Important:
At the end, there will be only one gluuPassportConfiguration
attribute in LDAP condensing the 3 sections (conf, idpInitiated, and providers). This means that existing values (ie. related to oauth providers) will be removed.
-
Add a
.bak
suffix to files passport-saml-config.json, passport-inbound-idp-initiated.json. Example: passport-saml-config.json.bak -
For
passport_social
andpassport_saml
scripts, remove the propertiesgeneric_remote_attributes_list
andgeneric_local_attributes_list
-
Update both scripts with the latest content (oxScript attr) and increase oxRevision attribute by one
-
Backup the current 3.1.6 node app /opt/gluu/node/passport and replace with latest app from https://ox.gluu.org/npm/passport/
-
Install the app (npm install ...)
-
Copy the files in
~/temp/mappings
into/opt/gluu/node/passport/server/mappings
(account the destination directory already has several files). Then delete~/temp/mappings
-
Start passport