Gathering detailed insights and metrics for hana-saml-wsse
Gathering detailed insights and metrics for hana-saml-wsse
Gathering detailed insights and metrics for hana-saml-wsse
Gathering detailed insights and metrics for hana-saml-wsse
npm install hana-saml-wsse
Typescript
Module System
Node Version
NPM Version
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
Some advanced SAML use cases involve a single logical transaction that spans one or more intermediate clients or servers. A common example includes a SAML-enabled web site acting on behalf of a logged-in user while accessing additional SAML-enabled services, which are not directly accessible by the user agent, e.g. a database. Generalizing this example, a number of intermediaries might be traversed before the final point of access. Popular ways of making this happen are SAML impersonation, SAML assertion forwarding and SAML IdP proxy.
All of them suck:
When a SAML assertion is used as a security token to authenticate/authorize people and software against a mission-critical service, it is important that the identities and order of intermediaries, if any, are expressed within the token in some fashion.
SAML assertion delegation moves beyond the forwarding scenario by adding information to the assertion that explicitly identifies the chain of parties through which a transaction flows. Delegation assures that all requests in the chain are routed back through the identity provider at each hop to cryptographically guarantee that each party has been authenticated and appropriate policy enforced. This finegrained and real-time enforcement capability is a key advantage over pure SAML forwarding and impersonation, at a price of additional back-channel operation for each delegation hop.
Shibboleth Identity Provider implements SAML 2.0 profile for assertion delegation (Liberty/IDWSF).
hana-saml-wsse is the corresponding client. It also implements an ECP client, which is handy for testing your delegation configuration, but can be very useful in its own right, e.g. if you are implementing impersonation or fowarding model.
The package name is historical; the client has been originally implemented for a specific use case that involved a SAP HANA database backend. Making Shibboleth delegation work with SAP HANA requires additional IdP configuration, which is not covered here.
This implementation is known to work with Shibboleth IdP 3.2. There is some indication that ECP and ID-WSF profiles are supported by some other open source and commercial IdP systems, but none of them were tested.
As it should be clear from the example below, ID-WSF requires that your IdP is configured to support X.509 client certificate authentication. The same applies to all TLS middleware you might have in front of your IdP, e.g. nginx, httpd, netscaler, etc. This is at least as complicated as it sounds, so good luck. Good starting points are:
Things get easier if you want to use this library in ECP mode. Although ECP does support X.509 auth, it is optional (you can use basic HTTP auth method).
inResponseTo
validation is supported and enabled by default.NotBeforeOrAfter
is not validated, but is returned in assertionInfo
object.wsa
profile does not work over plain HTTP, and never will.ecp
mode should work over plain HTTP, but this is a very bad idea.$ npm install hana-saml-wsse
The following configuration snippet assumes the following scenario:
webserver-sp
is allowed to obtain a
delegatable assertion using ECP at any time. Assertion is valid for 10 hours.webserver-sp
as its Audience
restriction is limited to webserver-sp
.webserver-sp
can
request additional, "delegated" assertions which will be valid for database-sp
,
each valid for 60 seconds. These delegated assertions are no further delegatable,
i.e. database-sp
is the final point of access.Note that, while requesting a delegated assertion,
webserver-sp
does not need to present actual credentials of the user (generally, username and password), and it is not expected to have them - instead, it presents a delegatable assertion as the means of confirming that it has the authority to impersonate that user ondatabase-sp
or elsewhere. The communication takes place over authenticated TLS channel, i.e. IdP uses TLS to ensure it is actually talking to the SP to which the delegatable assertion was originally issued. In essence, this is the whole idea of how assertion delegation works.
1<!-- conf/relying-party.xml --> 2 3<!-- 4 "delegation-predicate" is a reference to a bean that implements 5 com.google.common.base.Predicate<ProfileRequestContext<?,?>> interface. 6 It can be used to implement additional custom logic to selectively allow 7 or disallow delegation. In the most basic case, you want to implement a predicate that 8 always returns true. 9--> 10 11<bean parent="RelyingPartyByName" c:relyingPartyIds="#{{ 'webserver-sp' }}"> 12 <property name="profileConfigurations"> 13 <list> 14 <!-- serve long-lived delegatable assertions via ECP --> 15 <bean id="SAML2.ECP" 16 class="net.shibboleth.idp.saml.saml2.profile.config.ECPProfileConfiguration" 17 p:inboundInterceptorFlows="security-policy/saml2-ecp" 18 p:allowDelegation-ref="delegation-predicate" 19 p:assertionLifetime="PT600M" 20 /> 21 <!-- serve short-lived delegated assertions via ID-WSF --> 22 <bean id="Liberty.SSOS" 23 class="net.shibboleth.idp.saml.idwsf.profile.config.SSOSProfileConfiguration" 24 p:inboundInterceptorFlows="security-policy/saml2-idwsf-ssos" 25 p:maximumTokenDelegationChainLength="1" 26 p:allowDelegation="false" 27 p:delegationPredicate-ref="delegation-predicate" 28 p:additionalAudiencesForAssertion="#{{ 'database-sp' }}" 29 p:assertionLifetime="PT1M" 30 /> 31 </list> 32 </property> 33</bean>
SP metadata must inform IdP that SP is ready and willing to consume delegatable assertions,
as shown below. The Location
attribute of AssertionConsumerService
must match consumerURL
parameter
of hana-saml-wsse
client configuration, but this is a formality as SP is not expected
to actually respond on that URL.
1... 2<!-- SSOS --> 3<AssertionConsumerService 4 Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" 5 Location="https://my.org/Liberty/SSOS"/> 6 7<AttributeConsumingService> 8 <RequestedAttribute 9 NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" 10 Name="urn:liberty:ssos:2006-08" 11 FriendlyName="assertionDelegation" 12 isRequired="false" /> 13</AttributeConsumingService> 14...
The example below matches the IdP configuration above and:
deleg_test_repeat_ms
milliseconds.1// test.js 2var 3 hdb = require('hdb'), 4 precise = require('precise'), 5 moment = require('moment'), 6 xmlfmt = require('xmlfmt'), 7 WSS = require('hana-saml-wsse') 8; 9 10var 11 deleg_test_repeat_ms = 3000, 12 idpHost = 'idphost', 13 idpPort = 443, 14 http_ua = 'hana-wss-client/1.0', 15 hdb_conf = { 16 host: 'hanahost', 17 port: 30015 18 } 19; 20 21var conf = { 22 user : 'tj_holowaychuk', 23 pass : null, // leave blank for TLS CCA (@see user_key/user_cert) 24 25 idpHost : idpHost, 26 idpPort : idpPort, 27 28 idpId : 'idp-id', 29 spId : 'webserver-sp', 30 31 url: { 32 ecp : '/idp/profile/SAML2/SOAP/ECP', 33 wsa : '/idp/profile/IDWSF/SSOS' 34 }, 35 36 consumerURL : 'https://my.org/Liberty/SSOS', 37 38 idp_cert : './idp.pem', 39 40 // used both for signing and X.509 auth (WSA only) 41 sp_key : './sp_private_key.pem', 42 sp_cert : './sp_public_key.pem', 43 44 // optional TLS CCA authentication (ECP only) 45 user_key : './user.key', 46 user_cert : './user.crt', 47 48 sig_alg : 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', 49 50 tls_opt: { 51 hostname : idpHost, 52 port : idpPort, 53 method : 'POST', 54 headers : { 55 'Content-Type' : 'text/xml', 56 'Transfer-Encoding' : 'chunked', 57 'User-Agent' : http_ua 58 }, 59 // die on bad IdP cert 60 rejectUnauthorized: true 61 }, 62 63 log: console.log 64}; 65 66var client = new WSS.client(conf); 67 68function hdbtest(assertion, cb) { 69 var hdbclient = hdb.createClient(hdb_conf); 70 hdbclient.connect({ assertion: assertion }, (err) => { 71 if (err) { 72 console.error('[hdb] error:', err); 73 } else { 74 console.log('[hdb] i am', hdbclient.get('user')); 75 } 76 hdbclient.end(); 77 cb && cb(err); 78 }); 79} 80 81client.get('ecp', (err, delegatableAssertion, assertionInfo) => { 82 if (err) 83 return conf.log('[ecp] error:', err); 84 85 conf.log('[ecp] rcvd delegatable assertion, expires', 86 moment(assertionInfo.notOnOrAfter).fromNow()); 87 88 //conf.log(xmlfmt(delegatableAssertion)) 89 90 var delegator = () => { 91 var timer = precise().start(); 92 client.get('wsa', (err, assertion, assertionInfo) => { 93 if (err) 94 return conf.log('[wsa] error:', err); 95 96 //conf.log(xmlfmt(assertion)); 97 //conf.log(assertion); 98 99 conf.log('[wsa] rcvd delegated assertion in', 100 (timer.stop().diff()/1000000000).toFixed(2) + 's,', 101 'expires', moment(assertionInfo.notOnOrAfter).fromNow()); 102 103 hdbtest(assertion, () => { 104 if(!deleg_test_repeat_ms) 105 process.exit(0); 106 }); 107 }, delegatableAssertion); 108 }; 109 110 if (deleg_test_repeat_ms) 111 setInterval(delegator, deleg_test_repeat_ms); 112 else 113 delegator(); 114}); 115 116//:~
You should get something like:
$ node test.js
[ecp] using tls cca with user key
[ecp] rcvd delegatable assertion, expires in 10 hours
[wsa] using tls cca with SP key
[wsa] rcvd delegated assertion in 0.22s, expires in a minute
[hdb] i am tj_holowaychuk
[wsa] using tls cca with SP key
[wsa] rcvd delegated assertion in 0.14s, expires in a minute
[hdb] i am tj_holowaychuk
[wsa] using tls cca with SP key
[wsa] rcvd delegated assertion in 0.16s, expires in a minute
[hdb] i am tj_holowaychuk
[wsa] using tls cca with SP key
[wsa] rcvd delegated assertion in 0.11s, expires in a minute
[hdb] i am tj_holowaychuk
[wsa] using tls cca with SP key
[wsa] rcvd delegated assertion in 0.14s, expires in a minute
^C
SAML specs are fun:
MIT. Use at your own risk. As with all things SAML, always be sure you know what you are doing.
No vulnerabilities found.
No security vulnerabilities found.