The current JASPIC implementation within WildFly is based on the integration with the legacy PicketBox security SPIs, this task is to provide a clean JASPIC integration with WildFly Elytron. Additionally JSR-375 will be build on JASPIC, the JSR-375 implementation will be included as it's own task but the clean JASPIC implementation should take into account what is coming.
The JASPIC specification can be found under JSR-196
This initial feature request / analysis is covering the core JASPIC implementation as required for the servlet profile including backwards compatible activation of the existing PicketBox implementation.
This initial implementation does not cover the LoginModule profile which will be covered under WFLY-9737, additionally the initial Callbacks supported will be limited to those mandated by the JASPI specification, support for Elytron specific callbacks will be covered under ELY-1504.
Once complete it should be possible to make use of JASPIC with no reference to or configuration in the legacy security subsystem although use of LoginModules will be dependent on WFLY-9737 being implemented.
So for this first stage the core requirements being handled are: -
- Configuration of JASPI ServerAuthConfig
- Configuration associating the ServerAuthConfig with layer and appId to be returned by an AuthConfigProvider. (This may or may not be combined with #1)
- Support dynamic registration of custom AuthConfigProvider instances with the factory.
- Deployments using PicketBox defined JASPIC should deploy as before with no modification required.
- This should remain operational if the WildFly Elytron extension is not present in the application server.
- Real time updates to the AuthConfigFactory should apply immediately.
It is not a requirement of the feature request but it is anticipated that the Elytron / JASPI implementation will be usable with Undertow stand alone, this should allow for some isolated unit tests to be developed to detect issues without relying on a complete application server.
The application-security-domain resource was added to the Undertow subsystem as a mechanism to allow us to deploy using PicketBox by default but deploy using Elytron authentication where a mapping was found, at some point in the future the PicketBox subsystem could be removed entirely so we should ensure we have some approaches that do not depend on the use of the application-security-domain resource.
Within the legacy security subsystem JASPIC related configuration is associated with the security domain.
This implementation was only usable with the servlet profile as well as the login module profile.
As a web application is deployed a reference to the SecurityDomain is obtained, if that security domain contains JASPIC configuration then JASPIC will be enabled for the web application - if no configuration is present then JASPIC will not be enabled at all for the web application. This is contrary to the JASPIC specification where the decision to use JASPIC or not should be decided based on a call to https://docs.oracle.com/javaee/7/api/javax/security/auth/message/config/AuthConfigFactory.html#getConfigProvider-java.lang.String-java.lang.String-javax.security.auth.message.config.RegistrationListener-
Applications that wish to use JASPIC but not backed by a security domain configuration are forced to use a dummy domain like the example configuration for it to be enabled.
The default AuthConfigFactory if no other is registered is org.jboss.security.auth.message.config.JBossAuthConfigFactory, mappings can be added to this but by default at the time of authentication if there is no new match then an instance of org.jboss.security.auth.message.config.JBossAuthConfigProvider is returned. The JBossAuthConfigProvider works by obtaining the current SecurityContext and from this obtaining the SecurityDomain and from there accessing the JASPIC configuration on the domain.
Overall although a JASPIC configuration can be enabled it does not match the behaviour as defined in the specification.
- Specification says getConfigProvider() can be called and cached at deployment time but current impl does call it for each request IF JASPIC was at least discovered at the time of deployment.
Prior implementations handled JASPIC as a specific authentication mechanism, this had a side effect that changes specifically made for JASPIC would impact the other mechanism handling and subsequently updates for the other mechanisms would impact JASPIC - integrating WildFly Elytron changes were made to Undertow to make it easier to take full control of the security handlers, my intention is to keep the JASPIC integration as independent as possible to minimise requirement conflicts.
Comments captured against prior implementation JASPIC implementation issues · GitHub
Modes of Operation
Once implemented there will be three modes of operation.
Fully Integrated (Elytron)
In fully integrated mode a SecurityDomain will either be associated with the managed AuthConfig definition or a SecurityDomain will be associated with the deployment and the AuthConfig will either be managed or dynamically registered.
In this mode the identity established by the ServerAuthModule must be present in the SecurityDomain, the identity also must have been granted the LoginPermission.
Pure JASPI (Elytron)
The integration will operate in pure mode where no SecurityDomain was associated with the AuthConfig or the deployment, in this case the ServerAuthModule will be trusted to establish any identity it chooses and associate any groups it chooses - however as this does not map to a SecurityDomain SecurityIdentity this identity will only be usable within the servlet deployment and will not propagate in any outbound calls.
In both of the Elytron modes the selection of a JASPI mode will be made at the time of the request, this will allow runtime updates to the factory either via configuration or dynamic updates will be able to happen immediately. Initially updates to existing resources or the removal of resources may put the server into a reload required state but it should be possible to handle additions without requiring a reload. If an AuthConfig is available at runtime then the request will be executed using JASPI based authentication, if no AuthConfig can be identified then the default authentication for that deployment will be used which may be via an elytron HttpAuthenticationFactory or may be no authentication at all.
PicketBox Integration (Legacy)
At present if a deployment references a security domain and that security domain is not mapped using an application-security-domain resource then legacy security using Undertow mechanisms backed by a PicketBox domain will be used. This behaviour will remain.
In this situation PicketBox based JASPI will be used only if the associated PicketBox domain contains a JASPI configuraton. The PicketBox integration will retain any existing dynamic AuthConfig discovery it already supports, however this will not switch to an Elytron mode and will remain in a PicketBox mode.
Security Domain Selection
Where an AuthConfig definition is managed within the application server we will make it possible to optionally associate a SecurityDomain with the AuthConfig, where this AuthConfig is used this will always be the preferred SecurityDomain. The disadvantage of this association is the SecurityDomani will not be associated with the deployment class loader so calls to SecurityDomain.getCurrent() will not work, flexible association due to the invocation of HTTP Servlet Request methods such as login() may not be possible.
If there is no SecurityDomain associated with the AuthConfig (either managed or dynamically registered) then the SecurityDomain associated with the deployment will be used.
Finally if there is not SecurityDomain associated with the AuthConfig and no SecurityDomain associated with the deployment then the integration will operate in 'Pure JASPI' mode, any identity established will be visible using the servlet APIs and role based access will be possible but without a SecurityDomain there will be no identity to propagate for any calls to other secured resources so unless an alternative strategy is used to establish an identity the outbound call will be anonymous.
Two new attributes will be added to the application-security-domain resource: -
- enable-jaspi (Default true) - If an administrator wants to guarantee that JASPI will not be enabled even if a matching AuthConfig is found this should be set to true.
- security-domain (Mutually exclusive to http-authentication-factory) - Reference to a SecurityDomain that should be associated with the deployments class loader. This is only a resource association and will not guarantee JASPI authentication occurs as that will still be dependent on a matching AuthConfig.
Where the http-authentication-factory is registered the SecurityDomain used by that factory is associated with the deployments class loader, that behaviour will remain even if JASPI is in use - this way the http-authentication-factory can always offer 'backup' authentication mechanisms.
This will require some additional thought, in general we need to cover AuthConfig definitions which in turn will reference ServerAuthModule classes, somehow these will need to mapped using 'layer' and 'appId'. At some point within these configurations we will want an optional reference to a SecurityDomain.
I expect during the deployment process listeners will be registered with the AuthFactory to detect subsequent registrations, if possible it may be good to reference this at runtime making it easier for an administrator to check which mappings may be required.
Main Tracking Issue - WFLY-9067
Darran Lofthouse - email@example.com