Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add useFriendlyNames config option #389

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -130,6 +130,7 @@ type Profile = {
* `skipRequestCompression`: if set to true, the SAML request from the service provider won't be compressed.
* `authnRequestBinding`: if set to `HTTP-POST`, will request authentication from IDP via HTTP POST binding, otherwise defaults to HTTP Redirect
* `disableRequestACSUrl`: if truthy, SAML AuthnRequest from the service provider will not include the optional AssertionConsumerServiceURL. Default is falsy so it is automatically included.
* `useFriendlyNames`: if truthy `FriendlyName` from assertion will be used instead of `Name` for profile property name
* **InResponseTo Validation**
* `validateInResponseTo`: if truthy, then InResponseTo will be validated from incoming SAML responses
* `requestIdExpirationPeriodMs`: Defines the expiration time when a Request ID generated for a SAML request will not be valid if seen in a SAML response in the `InResponseTo` field. Default is 8 hours.
Expand Down
5 changes: 3 additions & 2 deletions lib/passport-saml/saml.js
Expand Up @@ -1031,10 +1031,11 @@ SAML.prototype.processValidlySignedAssertion = function(xml, samlResponseXml, in
return;
}
var value = attribute.AttributeValue;
var name = self.options.useFriendlyNames && attribute.$.FriendlyName ? attribute.$.FriendlyName : attribute.$.Name;
if (value.length === 1) {
profile[attribute.$.Name] = attrValueMapper(value[0]);
profile[name] = attrValueMapper(value[0]);
} else {
profile[attribute.$.Name] = value.map(attrValueMapper);
profile[name] = value.map(attrValueMapper);
}
});
}
Expand Down
54 changes: 53 additions & 1 deletion test/tests.js
Expand Up @@ -211,8 +211,60 @@ describe( 'passport-saml /', function() {
fakeClock.restore();
server.close(done);
});
});

describe('FriendlyName', function () {
var app, profile;

beforeEach(function () {
var check = capturedChecks.find(c => c.name === 'Testshib -- valid encrypted response should succeed')
var pp = new passport.Authenticator();
app = express();
app.use(bodyParser.urlencoded({extended: false}));
app.use(pp.initialize());
var config = check.config;
config.callbackUrl = 'http://localhost:3033/login';
config.useFriendlyNames = true;
config.passReqToCallback = false;
pp.use(new SamlStrategy(config, function (_profile, done) {
profile = _profile;
done(null, { id: profile.nameID });
})
);

fakeClock = sinon.useFakeTimers(Date.parse(check.mockDate));

app.post('/login',
pp.authenticate("saml"),
function (req, res) {
res.status(200).send("200 OK");
});

app.use(function (err, req, res, next) {
// console.log( err.stack );
res.status(500).send('500 Internal Server Error');
});
});

it('should use FriendlyName when useFriendlyNames set in config', function (done) {
server = app.listen(3033, function () {
var requestOpts = {
url: 'http://localhost:3033/login',
method: 'POST',
form: check.samlResponse
};

request(requestOpts, function (err, response, body) {
should.not.exist(err);
profile.should.not.have.property('urn:oid:1.3.6.1.4.1.5923.1.1.1.6')
profile.eduPersonPrincipalName.should.equal('myself@testshib.org')
profile.should.not.have.property('urn:oid:1.3.6.1.4.1.5923.1.1.1.7')
profile.eduPersonEntitlement.should.equal('urn:mace:dir:entitlement:common-lib-terms')
done()
});
});
});
})
});

describe( 'captured SAML requests /', function() {
var capturedChecks = [
Expand Down