Skip to content

fix(nameIdentifier): handle the case of not found nameIdentifier#20

Merged
forrest-ua merged 3 commits intoauth0:masterfrom
forrest-ua:handle-case-of-not-found-name-identifier
Oct 28, 2020
Merged

fix(nameIdentifier): handle the case of not found nameIdentifier#20
forrest-ua merged 3 commits intoauth0:masterfrom
forrest-ua:handle-case-of-not-found-name-identifier

Conversation

@forrest-ua
Copy link
Copy Markdown
Contributor

Description

This PR adds handling of the case when nameIdentifier could not be found within the mapped profile for some reason.

Testing

  • This change adds test coverage for new/changed/fixed functionality

Checklist

  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not master

Comment thread lib/wsfed.js
var profileMap = options.profileMapper(user);
var claims = profileMap.getClaims(options);
var ni = profileMap.getNameIdentifier(options);
if (!ni || !ni.nameIdentifier) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In saml11.create both the nameIdentifier and nameIdentifierFormat are optional.

https://github.com/auth0/node-saml/blob/a08d250d02938acde2c53d72858a78d33f4dd684/lib/saml11.js#L41-L42

I realise this is the same approach adopted in auth0/node-samlp#102 but is there a reason why it's preferable to fail here rather than not pass the options?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question @luuuis! I feel like the responsibility of the middleware should be to guarantee that meaningful response is returned. Otherwise, it's going to return the empty nameIdentifier without alert to the client and the client has to deal with it somehow. While empty nameIdentifier be a clear indication of the problem within used profile mapper.

On the other hand, somebody might say that it's the job of the profile mapper to guarantee the existence of nameIdentifier and fail otherwise, but it's not the obvious assumption. And I feel like failing fast is more robust and predictable option. WDYT?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. Even though the <NameIdentifier> is optional, for our purposes we always want to include one in the SAML assertions so it is appropriate to fail fast.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, for our purposes this would work just fine. I'm thinking: could this potentially be a breaking change for consumers of this lib? In other words, do you know if the name identifier is strictly required in the assertion and hence not finding one should result in us throwing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, it's a good question. So it might be a breaking change for those consumers, that:

  • use custom profile mapper that returns name identifier object without nameIdentifier claim inside
  • used profile mapper (default or custom) maps empty name identifier
    and expect an assertion to be successfully formed.

Reading SAML v1.1 spec, I don't see that <NameIdentifier> has to be a non-empty string. So it might be a valid case for some flow?

On the other hand, since a similar change has been done in samlp it seems nobody explicitly requested a possibility to support this scenario. What if this change will be released as MINOR or MAJOR change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After talking with @fadymak, given that we don't know if any consumer of the library really needs to explicitly pass empty nameIdentifier, it was decided not to introduce an extra complexity (of supporting requireNameIdentifier config option) for now and to go with this breaking change, releasing a major version.

This new config option requireNameIdentifier might be added in the future if the corresponding feedback will be received.

Comment thread test/fixture/server.js
getPostURL: getPostURL,
cert: credentials.cert,
key: credentials.key
}, module.exports.options))(req, res, function(err){
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing this why not pass in a profileMapper stub to start and have that behave differently in each test?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the current implementation, if we pass stubbed profile mapper, we wouldn't be able to test the behavior of picking default profile mapper PassportProfileMapper (existing tests basically), since the corresponding evaluation of which mapper to chose happens on server start (at the very beginning).

Another viable option is to leave the current test suite as it is, testing the default profile mapper, and have a separate test suite where we start a server with a stubbed profile mapper.

There are different options in the end, but honestly, I find the proposed approach of runtime building wsfed auth for testing the most flexible and easier to use. I saw it basically in node-samlp https://github.com/auth0/node-samlp/blob/master/test/fixture/server.js#L58-L70

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current approach is fine. 👍

Comment thread package.json
},
"devDependencies": {
"chai": "~1.5.0",
"debug": "~3.2.6",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this a missing dependency or perhaps when testing locally? I can't seem to find where it's used

Copy link
Copy Markdown
Contributor Author

@forrest-ua forrest-ua Oct 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sorry, forgot to mention this. This dev dependency is used by mocha. Automatically mocha picks the latest debug lib verison 4.x.x which uses features from ES2015 (like let keywords) and this is not compatible with node v4 (supported by this library). By pinpointing the debug version to 3.x.x. (3.2.6 is the latest) we can still successfully run tests for nodejs v4. Otherwise, tests are failing because of the usage of let by debug package for node v4 basically.

Comment thread lib/wsfed.js
var profileMap = options.profileMapper(user);
var claims = profileMap.getClaims(options);
var ni = profileMap.getNameIdentifier(options);
if (!ni || !ni.nameIdentifier) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, for our purposes this would work just fine. I'm thinking: could this potentially be a breaking change for consumers of this lib? In other words, do you know if the name identifier is strictly required in the assertion and hence not finding one should result in us throwing?

@forrest-ua forrest-ua force-pushed the handle-case-of-not-found-name-identifier branch from 279aa1f to 3bde2f7 Compare October 28, 2020 11:18
@forrest-ua
Copy link
Copy Markdown
Contributor Author

I've forced pushed in to purely update the commit message to reflect the breaking change. And also a small non-functional commit is added 3bde2f7 to enable commitlint and add standard-version.

@forrest-ua forrest-ua merged commit 0fd5541 into auth0:master Oct 28, 2020
@forrest-ua forrest-ua deleted the handle-case-of-not-found-name-identifier branch October 28, 2020 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants