此内容没有您所选择的语言版本。
Chapter 16. Java Authentication SPI for Containers (JASPI)
Java Authentication SPI for Containers (JASPI or JASPIC) is a pluggable interface for Java applications. It is defined in JSR-196 of the Java Community Process. Refer to http://www.jcp.org/en/jsr/detail?id=196 for details about the specification.
You can authenticate a JASPI provider by adding <authentication-jaspi> element to your security domain. The configuration is similar to that of a standard authentication module, but login module elements are enclosed in a <login-module-stack> element. The structure of the configuration is:
Example: Structure of the authentication-jaspi Element
The login module itself is configured the same way as a standard authentication module.
The web-based management console does not expose the configuration of JASPI authentication modules. You must stop the JBoss EAP running instance completely before adding the configuration directly to the EAP_HOME/domain/configuration/domain.xml file or the EAP_HOME/standalone/configuration/standalone.xml file.
Starting in JBoss EAP 7.3, the elytron subsystem provides an implementation of the Servlet profile from the Java Authentication SPI for Containers (JASPI). This allows tighter integration with the security features provided by Elytron.
Enabling JASPI for a Web Application
For the JASPI integration to be enabled for a web application, the web application needs to be associated with either an Elytron http-authentication-factory or a security-domain. By doing this, the Elytron security handlers get installed for the deployment and the Elytron security framework gets activated for the deployment.
When the Elytron security framework is activated for a deployment, the globally registered AuthConfigFactory is queried when requests are handled. It will identify if an AuthConfigProvider, which should be used for that deployment, has been registered. If an AuthConfigProvider is found, then JASPI authentication will be used instead of the deployment’s authentication configuration. If no AuthConfigProvider is found, then the authentication configuration for the deployment will be used instead. This could result in one of the three possibilities:
-
Use of authentication mechanisms from an
http-authentication-factory. -
Use of mechanisms specified in the
web.xml. - No authentication is performed if the application does not have any mechanisms defined.
Any updates made to the AuthConfigFactory are immediately available. This means if an AuthConfigProvider is registered and is a match for an existing application, it will start to be used immediately without requiring redeployment of the application.
All web applications deployed to JBoss EAP have a security domain, which will be resolved in the following order:
- From the deployment descriptors or annotations of the deployment.
-
The value defined on the
default-security-domainattribute on theundertowsubsystem. -
Default to
other.
It is assumed that this security domain is a reference to the PicketBox security domain, so the final step in activation is ensuring this is mapped to Elytron using an application-security-domain resource in the undertow subsystem.
This mapping can do one of the following:
Reference an
elytronsecurity domain directly, for example:/subsystem=undertow/application-security-domain=MyAppSecurity:add(security-domain=ApplicationDomain)
/subsystem=undertow/application-security-domain=MyAppSecurity:add(security-domain=ApplicationDomain)Copy to Clipboard Copied! Toggle word wrap Toggle overflow Reference a
http-authentication-factoryresource to obtain instances of authentication mechanisms, for example:/subsystem=undertow/application-security-domain=MyAppSecurity:add(http-authentication-factory=application-http-authentication)
/subsystem=undertow/application-security-domain=MyAppSecurity:add(http-authentication-factory=application-http-authentication)Copy to Clipboard Copied! Toggle word wrap Toggle overflow
The minimal steps to enable the JASPI integration are:
-
Leave the
default-security-domainattribute on theundertowsubsystem undefined so that it defaults toother. -
Add an
application-security-domainmapping fromotherto an Elytron security domain.
The security domain associated with a deployment in these steps is the security domain that will be wrapped in a CallbackHandler to be passed into the ServerAuthModule instances used for authentication.
Additional Options
Two additional attributes have been added to the application-security-domain resource to allow some further control of the JASPI behavior.
| Attribute | Description |
|---|---|
|
|
Can be set to |
|
|
By default, all identities are loaded from the security domain. If set to |
Subsystem Configuration
One way to register a configuration that will result in an AuthConfigProvider being returned for a deployment is to register a jaspi-configuration in the elytron subsystem.
The following command demonstrates how to add a configuration containing two ServerAuthModule definitions.
/subsystem=elytron/jaspi-configuration=simple-configuration:add(layer=HttpServlet, application-context="default-host /webctx", description="Elytron Test Configuration", server-auth-modules=[{class-name=org.wildfly.security.examples.jaspi.SimpleServerAuthModule, module=org.wildfly.security.examples.jaspi, flag=OPTIONAL, options={a=b, c=d}}, {class-name=org.wildfly.security.examples.jaspi.SecondServerAuthModule, module=org.wildfly.security.examples.jaspi}])
/subsystem=elytron/jaspi-configuration=simple-configuration:add(layer=HttpServlet, application-context="default-host /webctx", description="Elytron Test Configuration", server-auth-modules=[{class-name=org.wildfly.security.examples.jaspi.SimpleServerAuthModule, module=org.wildfly.security.examples.jaspi, flag=OPTIONAL, options={a=b, c=d}}, {class-name=org.wildfly.security.examples.jaspi.SecondServerAuthModule, module=org.wildfly.security.examples.jaspi}])
This results in the following configuration being persisted.
The name attribute is just a name that allows the resource to be referenced in the management model.
The layer and application-context attributes are used when registering this configuration with the AuthConfigFactory. Both of these attributes can be omitted allowing wildcard matching. The description attribute is also optional and is used to provide a description to the AuthConfigFactory.
Within the configuration, one or more server-auth-module instances can be defined with the following attributes.
-
class-name - The fully qualified class name of the
ServerAuthModule. -
module - The module to load the
ServerAuthModulefrom. - flag - The control flag to indicate how this module operates in relation to the other modules.
-
options - Configuration options to be passed into the
ServerAuthModuleon initialization.
Configuration defined in this way is immediately registered with the AuthConfigFactory. Any existing deployments using the Elytron security framework, that matches the layer and application-context, will immediately start making use of this configuration.
Programmatic Configuration
The APIs defined within the JASPI specification allow for applications to dynamically register custom AuthConfigProvider instances. However, the specification does not provide the actual implementations to be used or any standard way to create instances of the implementations. The Elytron project contains a simple utility that deployments can use to help with this.
The following code example demonstrates how to use this API to register a configuration similar to the one illustrated in the Subsystem Configuration above.
String registrationId = org.wildfly.security.auth.jaspi.JaspiConfigurationBuilder.builder("HttpServlet", servletContext.getVirtualServerName() + " " + servletContext.getContextPath())
.addAuthModuleFactory(SimpleServerAuthModule::new, Flag.OPTIONAL, Collections.singletonMap("a", "b"))
.addAuthModuleFactory(SecondServerAuthModule::new)
.register();
String registrationId = org.wildfly.security.auth.jaspi.JaspiConfigurationBuilder.builder("HttpServlet", servletContext.getVirtualServerName() + " " + servletContext.getContextPath())
.addAuthModuleFactory(SimpleServerAuthModule::new, Flag.OPTIONAL, Collections.singletonMap("a", "b"))
.addAuthModuleFactory(SecondServerAuthModule::new)
.register();
As an example, this code could be executed within the init() method of a Servlet to register the AuthConfigProvider specific for that deployment. In this code example, the application context has also been assembled by consulting the ServletContext.
The register() method returns the resulting registration ID that can also be used to subsequently remove this registration directly from the AuthConfigFactory.
As with the Subsystem Configuration, this call also has an immediate effect and will be live for all web applications using the Elytron security framework.
Authentication Process
Based on the configuration of the application-security-domain resource in the undertow subsystem, the CallbackHandler passed to the ServerAuthModule can operate in either of the following modes:
Integrated Mode
When operating in the integrated mode, although the ServerAuthModule instances will be handling the actual authentication, the resulting identity will be loaded from the referenced SecurityDomain using the SecurityRealms referenced by that SecurityDomain. In this mode, it is still possible to override the roles that will be assigned within the servlet container.
The advantage of this mode is that ServerAuthModules are able to take advantage of the Elytron configuration for the loading of identities, so that the identities stored in the usual locations, such as databases and LDAP, can be loaded without the ServerAuthModule needing to be aware of these locations. In addition, other Elytron configuration can be applied, such as role and permission mapping. The referenced SecurityDomain can also be referenced in other places, such as for SASL authentication or other non JASPI applications, all backed by a common repository of identities.
| Operation | Description |
|---|---|
|
|
The username and password will be used with the |
|
|
This Note
If an authenticated identity has already been established via the
If a
Where authorization of the anonymous identity is performed, the |
|
|
In this mode, the attribute loading, role decoding, and role mapping configured on the security domain are used to establish the identity. If this |
Non-Integrated Mode
When operating in non-integrated mode, the ServerAuthModules are completely responsible for all authentication and identity management. The specified Callbacks can be used to establish an identity. The resulting identity will be created on the SecurityDomain but it will be independent of any identities stored in referenced SecurityRealms.
The advantage of this mode is that JASPI configurations that are able to completely handle the identities can be deployed to the application server without requiring anything beyond a simple SecurityDomain definitions. There is no need for this SecurityDomain to actually contain the identities that will be used at runtime. The disadvantage of this mode is that the ServerAuthModule is now responsible for all identity handling, potentially making the implementation much more complex.
| Operation | Description |
|---|---|
|
|
The |
|
|
This
If a |
|
|
As the identity is created in this mode without loading from the |
validateRequest
During the call to validateRequest on the ServerAuthContext, the individual ServerAuthModule instances will be called in the order in which they are defined. A control flag can also be specified for each module. This flag defines how the response should be interpreted and if processing should continue to the next server authentication module or return immediately.
Control Flags
Whether the configuration is provided within the elytron subsystem or using the JaspiConfigurationBuilder API, it is possible to associate a control flag with each ServerAuthModule. If one is not specified, it defaults to REQUIRED. The flags have the following meanings depending on their result.
| Flag | AuthStatus.SEND_SUCCESS | AuthStatus.SEND_FAILURE, AuthStatus.SEND_CONTINUE |
|---|---|---|
| Required | Validation will continue to the remaining modules. Provided the requirements of the remaining modules are satisfied, the request will be allowed to proceed to authorization. | Validation will continue to the remaining modules; however, regardless of their outcomes, the validation will not be successful and control will return to the client. |
| Requisite | Validation will continue to the remaining modules. Provided the requirements of the remaining modules are satisfied, the request will be allowed to proceed to authorization. | The request will return immediately to the client. |
| Sufficient |
Validation is deemed successful and complete, provided no previous |
Validation will continue down the list of remaining modules. This status will only affect the decision if there are no |
| Optional |
Validation will continue to the remaining modules, provided any |
Validation will continue down the list of remaining modules. This status will only affect the decision if there are no |
For all ServerAuthModule instances, if they throw an AuthException, an error will be immediately reported to the client with no further module calls.
secureResponse
During the call to secureResponse, each ServerAuthModule is called, but this time in reverse order where a module only undertakes an action in secureResponse. If the module undertook an action in validateResponse, it is the responsibility of the module to track this.
The control flag has no effect on secureResponse processing. Processing ends when one of the following is true:
-
All of the
ServerAuthModuleinstances have been called. -
A module returns
AuthStatus.SEND_FAILURE. -
A module throws an
AuthException.
SecurityIdentity Creation
Once the authentication process has completed, the org.wildfly.security.auth.server.SecurityIdentity for the deployment’s SecurityDomain will have been created as a result of the Callbacks to the CallbackHandler. Depending on the Callbacks, this will either be an identity loaded directly from the SecurityDomain, or it will be an ad-hoc identity described by the callbacks. This SecurityIdentity will be associated with the request, in the same way it is done for other authentication mechanisms.