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

Support for AttributeConsumingService #406

Open
brandon-leapyear opened this issue Dec 4, 2019 · 6 comments
Open

Support for AttributeConsumingService #406

brandon-leapyear opened this issue Dec 4, 2019 · 6 comments

Comments

@brandon-leapyear
Copy link
Contributor

Hi, is there a way to configure <md:AttributeConsumingService> with this library? Or do attribute requirements have to be communicated out-of-band to the IdP?

https://en.wikipedia.org/wiki/SAML_Metadata#Service_Provider_Metadata

@markstos
Copy link
Contributor

When I use Github search to search the code for "AttributeConsumingService", I get back no results, so I'm guessing the answer is "not currently". If it makes the project more spec-compliant, a pull request is welcome. It should include updating the documentation, adding test coverage, references to the part of the spec being implemented and ideally some peer review.

@aeaton-overleaf
Copy link

aeaton-overleaf commented May 6, 2021

It does seem strange that passport-saml has an attributeConsumingServiceIndex option, but nothing in the generateServiceProviderMetadata function that builds the metadata to add an AttributeConsumingService block.

generateServiceProviderMetadata(decryptionCert: string | null, signingCert?: string | null) {
const metadata: ServiceMetadataXML = {
EntityDescriptor: {
"@xmlns": "urn:oasis:names:tc:SAML:2.0:metadata",
"@xmlns:ds": "http://www.w3.org/2000/09/xmldsig#",
"@entityID": this.options.issuer,
"@ID": this.options.issuer.replace(/\W/g, "_"),
SPSSODescriptor: {
"@protocolSupportEnumeration": "urn:oasis:names:tc:SAML:2.0:protocol",
},
},
};
if (this.options.decryptionPvk != null) {
if (!decryptionCert) {
throw new Error(
"Missing decryptionCert while generating metadata for decrypting service provider"
);
}
}
if (this.options.privateKey != null) {
if (!signingCert) {
throw new Error(
"Missing signingCert while generating metadata for signing service provider messages"
);
}
}
if (this.options.decryptionPvk != null || this.options.privateKey != null) {
metadata.EntityDescriptor.SPSSODescriptor.KeyDescriptor = [];
if (this.options.privateKey != null) {
signingCert = signingCert!.replace(/-+BEGIN CERTIFICATE-+\r?\n?/, "");
signingCert = signingCert.replace(/-+END CERTIFICATE-+\r?\n?/, "");
signingCert = signingCert.replace(/\r\n/g, "\n");
metadata.EntityDescriptor.SPSSODescriptor.KeyDescriptor.push({
"@use": "signing",
"ds:KeyInfo": {
"ds:X509Data": {
"ds:X509Certificate": {
"#text": signingCert,
},
},
},
});
}
if (this.options.decryptionPvk != null) {
decryptionCert = decryptionCert!.replace(/-+BEGIN CERTIFICATE-+\r?\n?/, "");
decryptionCert = decryptionCert.replace(/-+END CERTIFICATE-+\r?\n?/, "");
decryptionCert = decryptionCert.replace(/\r\n/g, "\n");
metadata.EntityDescriptor.SPSSODescriptor.KeyDescriptor.push({
"@use": "encryption",
"ds:KeyInfo": {
"ds:X509Data": {
"ds:X509Certificate": {
"#text": decryptionCert,
},
},
},
EncryptionMethod: [
// this should be the set that the xmlenc library supports
{ "@Algorithm": "http://www.w3.org/2001/04/xmlenc#aes256-cbc" },
{ "@Algorithm": "http://www.w3.org/2001/04/xmlenc#aes128-cbc" },
{ "@Algorithm": "http://www.w3.org/2001/04/xmlenc#tripledes-cbc" },
],
});
}
}
if (this.options.logoutCallbackUrl != null) {
metadata.EntityDescriptor.SPSSODescriptor.SingleLogoutService = {
"@Binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
"@Location": this.options.logoutCallbackUrl,
};
}
if (this.options.identifierFormat != null) {
metadata.EntityDescriptor.SPSSODescriptor.NameIDFormat = this.options.identifierFormat;
}
if (this.options.wantAssertionsSigned) {
metadata.EntityDescriptor.SPSSODescriptor["@WantAssertionsSigned"] = true;
}
metadata.EntityDescriptor.SPSSODescriptor.AssertionConsumerService = {
"@index": "1",
"@isDefault": "true",
"@Binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
"@Location": this.getCallbackUrl(),
};
return buildXmlBuilderObject(metadata, true);
}

@aeaton-overleaf
Copy link

aeaton-overleaf commented May 6, 2021

Maybe something like this, at the end of generateServiceProviderMetadata?

if (this.options.attributeConsumingServices) {
    this.options.attributeConsumingServices.forEach((attributeConsumingService, index) => {
      metadata.EntityDescriptor.SPSSODescriptor.AttributeConsumingService = {
        '@index': index,
        '@isDefault': attributeConsumingService.isDefault,
        ServiceName: attributeConsumingService.name,
        ServiceDescription: attributeConsumingService.description,
        RequestedAttribute: attributeConsumingService.requestedAttributes.map(requestedAttribute => ({
          '@isRequired': requestedAttribute.isRequired,
          '@FriendlyName': requestedAttribute.friendlyName,
          '@Name': requestedAttribute.name,
          '@NameFormat': requestedAttribute.nameFormat
        }))
      };
    })
  }

https://wiki.shibboleth.net/confluence/display/CONCEPT/MetadataForSP#MetadataForSP-DocumentingAttributes

@cjbarth
Copy link
Collaborator

cjbarth commented Oct 1, 2021

@aeaton-overleaf , are you willing to put up a PR for this?

@aeaton-overleaf
Copy link

@cjbarth I'm not planning to work on this immediately, but a colleague may be able to write up a PR later this year (pending other priorities - let me know if there's a need for it sooner).

@cjbarth
Copy link
Collaborator

cjbarth commented Oct 4, 2021

As this is a community-driven project, we look forward to, and depend upon, those that notice missing features putting up a PR to fill that need. The maintainers will be here to help the PR along.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants