We continue to improve the Kentor.AuthServices SAML2 Service Provider for ASP.NET with the release of version 0.8.0. With this release the entire configuration system has been rebuilt, to enable configuration from other sources than the config file. This is good news for anyone thinking of integrating Kentor AuthServices in an application where configuration is offered through a user interface. There has also been further support for federations added, with administrative metadata now being exported as well as support attribute consuming services and the Idp discovery extensions to metadata.
- Automatic generation of service provider URLs, removing configuration.
- Configuration can now be supplied from code and not only in config file.
- Administrative metadata (organization and contactPerson) support.
- Serialization of SAML Attributes.
- Support for Bootstrapcontext, saving incoming assertion in the resulting identity.
- Fixed new principal returned by ClaimsAuthenticationManager being ignored.
- Attribute consuming service support in metadata and AuthnRequest.
- Discovery service response location included in metadata if use of discovery service is enabled.
- Fixed null reference exception on HTTP POST with owin middleware.
Automatic Generation of Service Provider Urls
With increasing functionality, the number of urls in the config for various functions in the service provider has been growing. The urls were not completely independent, e.g. the discovery service response url had to be set to the url of the sign in command, but nothing prevented them from being set to totally different things. There were also some differences between the http module, the MVC controller and the Owin middleware in how the urls were handled.
With this release the urls are now automatically derived based on the
modulePath option in the configuration. There are now only two urls left to configure.
<kentor.authServices entityId="https://github.com/KentorIT/authservices" returnUri="http://localhost/LoggedIn" discoveryServiceUrl="http://dicoveryservice.example.com/DiscoveryService" >
The entity id is usually a url to the metadata, but not always. That means that it has to be separately configurable. The
returnUri can’t be derived as that is application dependent. The
discoveryServiceUrl isn’t even in the application itself; it’s external and part of the federation configuration.
Configuration in Code
When the Kentor.AuthServices project started it only offered an http module. With http modules being heavily tied to configuration in
web.config it was natural to keep the configuration in the config file too. The code base soon was full of references to
KentorAuthServicesSection.Current. That wasn’t a problem until the owin middleware was created. An Owin middleware is configured by handling it an options object, that has no connection to the
With this release, there is now support for providing options independently of the
web.config file when using the middleware. The http module and the MVC controller still reference the
web.config as the source for their configuration. With the configuration now being dependency injected through an
IOptions instance it is possible to have an own source of configuration. That could be hard coded information, or loaded from a database where user supplied settings are stored. It is even possible to change the options during runtime, without having to restart the application, by changing the
IOptions instance that was used when registering the middleware.
In SAML2 federations each entity is represented by metadata. Some of the metadata is important technically and some is just for information. Administrative metadata is just informational, but is nice to have and it is even required by some federation operators.
Kentor.AuthServices supports providing organization and contact person details. When using configuration in code, the full possibilities permitted by the SAML2 metadata standard can be set. When using the configuration file, some settings have been simplified to not clutter the configuration structure. A sample code><metadata> setting in the config could looks like this.
<metadata> <organization name="Kentor IT AB" displayName="Kentor" url="http://www.kentor.se" language="sv"/> <contactPerson type="Technical" email="[email protected]" /> <contactPerson type="Support" email="[email protected]" /> </metadata>
Those setting will generate this metadata.
<EntityDescriptor ID="_144c235b-d210-4d62-80c8-168ac9899cd3" entityID="http://localhost:57294/AuthServices" cacheDuration="PT1H" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"> <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:57294/AuthServices/Acs" index="0" isDefault="true"/> </SPSSODescriptor> <Organization> <OrganizationName xml:lang="sv">Kentor IT AB</OrganizationName> <OrganizationDisplayName xml:lang="sv">Kentor</OrganizationDisplayName> <OrganizationURL xml:lang="sv">http://www.kentor.se/</OrganizationURL> </Organization> <ContactPerson contactType="technical"> <EmailAddress>[email protected]</EmailAddress> </ContactPerson> <ContactPerson contactType="support"> <EmailAddress>[email protected]</EmailAddress> </ContactPerson> </EntityDescriptor>
Serialization of SAML Attributes and BoostrapContext
Thanks to a contribution from Jozed Raschmann, there is now support for serializing
Saml2Statement instances into SAML2 attribute statements. They are automatically included when serializing a
Saml2Assertion to XML.
Jozef has also added support for setting the
BoostrapContext property of generated claims identities. When enabled, the
BootstrapContext property of the generated identity will contain a reference to the source
Saml2SecurityToken that was read from the incoming saml response.
Saving of the
BootstrapContext is enabled through the
FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SaveBootstrapContext setting, which can be set by code or in the
Attribute Consuming Service Support
A service provider can indicate what attributes it wants to receive in incoming assertions, by providing a
AttributeConsumingService in the metadata. The
AuthnRequest generated by the service provider contains a reference to the attribute consuming service in the metadata. To enable attributes in Kentor AuthServices’ metadata, it is added to the configuration.
<metadata> <requestedAttributes> <add friendlyName="Some Name" name="urn:someName" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /> <add name="Minimal" /> </requestedAttributes> </metadata>
This will generate this block in the metadata.
<AttributeConsumingService index="0" isDefault="false"> <ServiceName xml:lang="en">SP</ServiceName> <RequestedAttribute Name="urn:someName" isRequired="true" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Some Name"/> <RequestedAttribute Name="Minimal" isRequired="false" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"/> </AttributeConsumingService>
If an attribute consuming service is present in the configuration, it will automatically be indicated in any generated
Discovery Service Response Location in Metadata
If a discovery service url is specified in the configuration, the response location is automatically generated and included in the metadata.
<Extensions> <DiscoveryResponse Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" Location="http://localhost:57294/AuthServices/SignIn" index="0" isDefault="true" xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"/> </Extensions>
A couple of bugs have been fixed as well.
- Fixed new principal returned by
- Fixed null reference exception on HTTP POST with owin middleware.
With every release, we are adding more features to AuthServices to make it more usable. If you use it, please let us know! It’s always encouraging to know that someone is using the code we put effort into releasing.
The next release will probably contain automatic refresh of loaded metadata, based on the
cacheDuration found in the metadata. There’s also some talk about restructuring the code base by introducing namespaces. I know that there is work in progress on signing generated
AuthnRequest and I would also love to update the stub idp to allow custom assertions to be generated in the response.
If you have any specific features you want to get included, please head over to the issue list on github and make your voice heard or even better, provide a pull request.