Jakarta EE Security Extensions
This section documents available extensions for custom authentication mechanisms and identity store configurations that can be used in any Jakarta EE application.
Custom Authentication Mechanisms
The Payara Platform Public API offers the following custom authentication mechanisms for use cases that aren’t covered in the Jakarta EE Security API.
Client Certificate Authentication Mechanism
The Jakarta EE Security API doesn’t include any specific authentication mechanisms for support client certificate validation, so the @CertificateAuthenticationMechanismDefinition
can be used to instruct any application to initiate client certificate validation when any HTTP request is to be authenticated.
This authentication mechanism will mostly be used in conjunction with the @CertificateIdentityStoreDefinition (see below for more information), since certificates are probably stored in a client certificate security realm.
|
Example
The following code sample illustrates how to configure a client certificate authentication mechanism:
@ApplicationScoped
@ApplicationPath("/rest")
@DeclareRoles({ "a", "b" })
@CertificateAuthenticationMechanismDefinition
@CertificateIdentityStoreDefinition("certificate-realm")
public class MyRestApp extends Application {
}
Two Identity Stores Authentication Mechanism
By default, when multiple identity stores are available to the Servlet container, user credentials will get validated against all of them and the authentication of a user will be considered successful if at least one identity store returns a VALID
result. In some cases this might not be the desired solution, so the @TwoIdentityStoreAuthenticationMechanismDefinition
allows users to configure a special authentication mechanism that validates user credentials against 2 identity stores and is successful if both of them return a VALID
result.
This authentication mechanism is based on the form-based authentication mechanism and requires a call to the SecurityContext.authenticate() method for each identity store validation. In case of further calls to this method an IllegalStateException will be thrown.
|
Configuration
The @TwoIdentityStoreAuthenticationMechanismDefinition
annotation can be configured with the following settings.
Option |
Required |
Description |
|
true |
A |
Example
The following code sample authenticates a user by using both single username/password credentials and a Yubikey code. Observe the 2 calls made to the SecurityContext.authenticate()
method:
@TwoIdentityStoreAuthenticationMechanismDefinition(loginToContinue
= @LoginToContinue(loginPage = "/login", errorPage = "failure")
)
@WebServlet("/Login")
public class LoginServlet extends HttpServlet {
@Inject
private SecurityContext securityContext;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
printHeaders(out);
out.println("<form action=\"Login\" method=\"post\">");
out.println("Username: ");
out.println("<input type=\"text\" name=\"username\"></br>");
out.println("Password: ");
out.println("<input type=\"password\" name=\"password\"></br>");
out.println("Yubikey Code: ");
out.println("<input type=\"password\" name=\"yubikey\"></br>");
out.println("<input type=\"submit\" value=\"submit\"></input>");
out.println("</form");
out.println("</body></html>");
out.flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Credential firstCredential = new UsernamePasswordCredential(req.getParameter("username"), req.getParameter("password"));
Credential secondCredential = new YubikeyCredential(req.getParameter("yubikey"));
// First call to securityContext.authenticate()
securityContext.authenticate(req, resp, new AuthenticationParameters().credential(firstCredential));
// Second call to securityContext.authenticate()
AuthenticationStatus status = securityContext.authenticate(req, resp, new AuthenticationParameters().credential(secondCredential));
PrintWriter out = resp.getWriter();
printHeaders(out);
if (status.equals(AuthenticationStatus.SUCCESS)){
out.println("Successfully logged in");
}
else {
PrintWriter out = resp.getWriter();
printHeaders(out);
out.println("Failed to log in");
}
out.flush();
}
private void printHeaders(PrintWriter out){
out.println("<html>");
out.println("<head>");
out.println("<title>Two Identity Stores Authentication</title>");
out.println("</head>");
out.println("<body>");
}
}
Custom Identity Stores
By default, the Jakarta EE Security API only instructs containers to implement identity stores for the following types:
-
LDAP directories through the
@LdapIdentityStoreDefinition
annotation. -
Relational databases through the
@DatabaseIdentityStoreDefinition
annotation.
The following annotations serve to provide additional identity store configurations, by allowing the mapping an existing Payara Platform security realm
Basic Realm Identity Store
The @RealmIdentityStoreDefinition
annotation allows users to plug-in any existing security realm as a valid identity store definition.
No additional configuration settings or properties are available, so in case of needing further control over the store definition, see the more specific annotations defined below. |
Configuration
The @RealmIdentityStoreDefinition
annotation is configured with the options as shown below.
Option |
Description |
Default |
Required |
|
The name of an existing security realm. |
<Default Realm> |
|
Example
The following code sample illustrates how to configure the default file
security realm as an identity store:
@ApplicationScoped
@ApplicationPath("/rest")
@DeclareRoles({ "a", "b"})
@BasicAuthenticationMechanismDefinition(realmName = "file")
@RealmIdentityStoreDefinition("file")
public class MyRestApp extends Application {
}
The RealmIdentityStoreDefinition is a repeatable annotation, hence multiple security realms can be used in sequence to define more than one identity store
|
@ApplicationScoped
@ApplicationPath("/rest")
@DeclareRoles({ "a", "b"})
@BasicAuthenticationMechanismDefinition
@RealmIdentityStoreDefinition("realm1")
@RealmIdentityStoreDefinition("realm2")
public class MyRestApp extends Application {
}
File Identity Store
The @FileIdentityStoreDefinition
annotation allows users to plug in an existing file security realm (com.sun.enterprise.security.auth.realm.file.FileRealm
) as a valid identity store definition.
If no realm is found with the defined name then a new realm will register on the server’s configuration using the create-auth-realm asadmin command.
|
Configuration
The file realm identity store can be configured via both @FileIdentityStoreDefinition
annotation attributes and MicroProfile Configuration properties. Here’s a list of all available and equivalent settings:
Option |
MP Config Property |
Description |
Default |
Required |
|
The name of the realm. |
|
|
|
|
|
The location of the file to store user credentials locally. If no file name is defined then the realm name is used as the file name. |
<Realm Name> |
|
|
|
Users will get assigned membership to these groups automatically on successful authentication |
|
|
|
|
The JAAS Context of the file realm. |
|
|
If both an annotation attribute and a MicroProfile Configuration property are defined for the same option then the configuration property always takes precedence. |
Example
The following code sample illustrates how to configure a file realm identity store:
@ApplicationScoped
@ApplicationPath("/rest")
@DeclareRoles({ "a", "b"})
@BasicAuthenticationMechanismDefinition(realmName = "file-realm")
@FileIdentityStoreDefinition("file-realm")
public class MyRestApp extends Application {
}
Client Certificate Identity Store
The @CertificateIdentityStoreDefinition
annotation allows users to plug-in an existing client certificate
security realm (com.sun.enterprise.security.auth.realm.certificate.CertificateRealm
) as a valid identity store definition.
If no realm is found with the defined name then a new realm will register on the server’s configuration using the create-auth-realm asadmin command.
|
Configuration
The certificate realm identity store can be configured via both @CertificateIdentityStoreDefinition
annotation attributes and MicroProfile Configuration properties. Here’s a list of all available and equivalent settings:
Option |
MP Config property |
Description |
Default |
Required |
|
The name of the certificate realm. |
|
|
|
|
|
Users will get assigned membership to these groups automatically on successful authentication. |
|
If both an annotation attribute and a MicroProfile Configuration property are defined for the same option then the configuration property always takes precedence. |
Example
The following code sample illustrates how to configure a certificate realm identity store:
@ApplicationScoped
@ApplicationPath("/rest")
@DeclareRoles({ "a", "b" })
@CertificateAuthenticationMechanismDefinition
@CertificateIdentityStoreDefinition("certificate-realm")
public class MyRestApp extends Application {
}
PAM Identity Store
The @PamIdentityStoreDefinition
annotation allows users to plug-in an existing PAM (Privileged Access Management) security realm (com.sun.enterprise.security.auth.realm.pam.PamRealm
) as a valid identity store definition.
If no realm is found with the defined name then a new realm will register on the server’s configuration using the create-auth-realm asadmin command.
|
Configuration
The pam realm identity store can be configured via both @PamIdentityStoreDefinition
annotation attributes and MicroProfile Configuration properties. Here’s a list of all available and equivalent settings:
Option |
MP Config property |
Description |
Default |
Required |
|
The name of PAM realm. |
|
||
|
|
Users will get assigned membership to these groups automatically on successful authentication. |
|
|
|
|
The JAAS Context of the PAM realm. |
|
|
Example
The following code sample illustrates how to configure a PAM realm identity store:
@ApplicationScoped
@ApplicationPath("/rest")
@DeclareRoles({ "a", "b"})
@BasicAuthenticationMechanismDefinition(realmName = "pam-realm")
@PamIdentityStoreDefinition("pam-realm")
public class MyRestApp extends Application {
}
If both an annotation attribute and a MicroProfile Configuration property are defined for the same option then the configuration property always takes precedence. |
Solaris Identity Store
The @SolarisIdentityStoreDefinition
annotation allows users to plug in an existing Solaris security realm (com.sun.enterprise.security.auth.realm.solaris.SolarisRealm
) as a valid identity store definition.
If no realm is found with the defined name then a new realm will register on the server’s configuration using the create-auth-realm asadmin command.
|
Configuration
The Solaris realm identity store can be configured via both @SolarisIdentityStoreDefinition
annotation attributes and MicroProfile Configuration properties. Here’s a list of all available and equivalent settings:
Option |
MP Config property |
Description |
Default |
Required |
|
The name of the Solaris realm. |
|
||
|
|
Users will get assigned membership to these groups automatically on successful authentication. |
|
|
|
|
The JAAS Context of the Solaris realm. |
|
|
If both an annotation attribute and a MicroProfile Configuration property are defined for the same option then the configuration property always takes precedence. |
Example
The following code sample illustrates how to configure a Solaris realm identity store:
@ApplicationScoped
@ApplicationPath("/rest")
@DeclareRoles({ "a", "b"})
@BasicAuthenticationMechanismDefinition(realmName = "solaris-realm")
@SolarisIdentityStoreDefinition("solaris-realm")
public class MyRestApp extends Application {
}