Working on SLO

This commit is contained in:
Steffo Weber 2015-08-05 18:08:36 +02:00
parent 67efa24ee4
commit 9b07bcb310
4 changed files with 48 additions and 15 deletions

View file

@ -19,10 +19,10 @@ For OpenAM, see the example app `example-openam`.
## Usage
Put SAML settings in eg `settings.json` like so:
Put SAML settings in eg `server/lib/settings.js` like so:
```
"saml":[{
settings = {"saml":[{
"provider":"openam",
"entryPoint":"https://openam.idp.io/openam/SSORedirect/metaAlias/zimt/idp",
"issuer": "https://sp.zimt.io/", //replace with url of your app
@ -30,7 +30,9 @@ Put SAML settings in eg `settings.json` like so:
"privateKeyFile": "certs/mykey.pem", // path is relative to $METEOR-PROJECT/private
"publicCertFile": "certs/mycert.pem" // eg $METEOR-PROJECT/private/certs/mycert.pem
}]
}]}
Meteor.settings = settings;
```
in some template
@ -71,7 +73,7 @@ and if SingleLogout is needed
1. Create a Meteor project by `meteor create sp` and cd into it.
2. Add `steffo:meteor-accounts-saml`
3. Create a `settings.json` file as described above
3. Create `server/lib/settings.js` as described above. Since Meteor loads things in `server/lib` first, this ensures that your settings are respected even on Galaxy where you cannot use `meteor --settings`.
4. Put your private key and your cert (not the IDP's one) into the "private" directory. Eg if your meteor project is at `/Users/steffo/sp` then place them in `/Users/steffo/sp/private`
5. Check if you can receive SP metadata eg via `curl http://localhost:3000/_saml/metadata/openam`. Output should look like:
@ -101,7 +103,7 @@ and if SingleLogout is needed
1. I prefer using OpenAM realms. Set up a realm using a name that matches the one in the entry point URL of the `settings.json` file: `https://openam.idp.io/openam/SSORedirect/metaAlias/<YOURREALM>/idp`; we used `zimt` above.
2. Save the SP metadata (obtained in Step 5 above) in a file `sp-metadata.xml`.
3. Logon OpenSSO console as `amadmin` and select _Common Tasks > Register Remote Service Provider_
4. Select the corresponding real and upload the metadata. If all goes well the new SP shows up under _Federation > Entity Providers_
4. Select the corresponding real and upload the metadata (alternatively, point OpenAM to the SP's metadata URL eg `http://sp.meteor.com/_saml/metadata/openam`). If all goes well the new SP shows up under _Federation > Entity Providers_

View file

@ -33,7 +33,8 @@ Accounts.saml.initiateLogin = function(options, callback, dimensions) {
Accounts.saml.idpInitiatedSLO = function(options){
//Meteor.absoluteUrl("_saml/logout/"+options.provider+"/"+options.credentialToken
console.log("Options: " + JSON.stringify(options));
location.href (Meteor.absoluteUrl("_saml/logout/"+options.provider));
//location.href(Meteor.absoluteUrl("_saml/sloInit/"+options.provider));
window.open(Meteor.absoluteUrl("_saml/sloInit/"+options.provider));
}
var openCenteredPopup = function(url, width, height) {
@ -75,6 +76,7 @@ Meteor.loginWithSaml = function(options, callback) {
Meteor.logoutWithSaml = function(options, callback) {
options = options || {};
Accounts.saml.idpInitiatedSLO(options, callback);
Accounts.saml.idpInitiatedSLO(options, callback);
};

View file

@ -6,6 +6,17 @@ var Fiber = Npm.require('fibers');
var connect = Npm.require('connect');
RoutePolicy.declare('/_saml/', 'network');
Meteor.methods({
samlLogout: function (text) {
// Make sure the user is logged in before inserting a task
if (! Meteor.userId()) {
throw new Meteor.Error("not-authorized");
} else {
console.log("Logout request from " + JSON.stringify(Meteor.userId()));
}
}
})
Accounts.registerLoginHandler(function (loginRequest) {
if (!loginRequest.saml || !loginRequest.credentialToken) {
return undefined;
@ -119,6 +130,22 @@ middleware = function (req, res, next) {
res.end();
//closePopup(res);
break;
case "sloInit":
_saml = new SAML(service);
console.log("LOGOUT INITIATED");
var relayState = Meteor.absoluteUrl();
//debugger
_saml.getLogoutUrl(req, function (err, url) {
if (err)
throw new Error("Unable to generate SAML logout request");
res.writeHead(302, {
'Location': url
});
res.end();
});
break;
case "sloRedirect":
break;
case "authorize":
service.callbackUrl = Meteor.absoluteUrl("_saml/validate/" + service.provider);
service.id = samlObject.credentialToken;

View file

@ -69,6 +69,7 @@ SAML.prototype.signRequest = function (xml) {
return signer.sign(this.options.privateKey, 'base64');
}
SAML.prototype.generateAuthorizeRequest = function (req) {
var id = "_" + this.generateUniqueID();
var instant = this.generateInstant();
@ -107,18 +108,19 @@ SAML.prototype.generateLogoutRequest = function (req) {
var id = "_" + this.generateUniqueID();
var instant = this.generateInstant();
//samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
// ID="_135ad2fd-b275-4428-b5d6-3ac3361c3a7f" Version="2.0" Destination="https://idphost/adfs/ls/"
//IssueInstant="2008-06-03T12:59:57Z"><saml:Issuer>myhost</saml:Issuer><NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
//NameQualifier="https://idphost/adfs/ls/">myemail@mydomain.com</NameID<samlp:SessionIndex>_0628125f-7f95-42cc-ad8e-fde86ae90bbe
//</samlp:SessionIndex></samlp:LogoutRequest>
if (Meteor.settings.debug) {
console.log("Request" + JSON.stringify(req.socket));
}
var request = "<samlp:LogoutRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" "+
"xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\""+id+"\" Version=\"2.0\" IssueInstant=\""+instant+
"\" Destination=\""+this.options.entryPoint + "\">" +
"\" Destination=\""+this.options.idpSLORedirectURL + "\">" +
"<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">" + this.options.issuer + "</saml:Issuer>"+
"<saml:NameID Format=\""+req.user.nameIDFormat+"\">"+req.user.nameID+"</saml:NameID>"+
"<saml:NameID Format=\""+this.options.identifierFormat+"\">"+Meteor.userId()+"</saml:NameID>"+
"</samlp:LogoutRequest>";
if (Meteor.settings.debug) {
console.log("------- SAML Logout request -----------");
console.log(request);
}
return request;
}