General concept of security in Java EE
Java standard security is implemented with the security manager and policy files, and is extended by the Java Enterprise Edition in a completely transparent way for the developer; like every other service offered by the platform.
If you are an Enterprise Bean developer, you can develop knowing that the container will take care of the sensitive task of securing your data in the same way it takes care of remoting, translating from HTTP protocol to servlet method call, and transaction management. Obviously, it is impossible for the container to be aware of the infrastructure in which it will be deployed, so there are a lot of standard ways to extend it in order to let it work with a new RDBMS: installing the Java Database Connectivity (JDBC) driver JAR files or a new transactional resource that implements the resource adapter contract.
This principle applies to security as well; but until Java EE 6 there were no standard methods of implementing a new Authentication Provider, or whatever is inherent to security. As we'll see, this new version makes it mandatory that containers implement JASPIC 1.0, but many of them implement it in parallel and WebLogic 12c is no exception. If you need to implement something that is not "simple", custom Providers with custom API are required.
In Java EE, the developer interacts with the container using declarative annotations or XML descriptors. When you need to secure a URL managed by a servlet, all you need to do is annotate that servlet with the @ServletSecurity
annotation along with a list of allowed roles, as shown in the following code snippet:
@WebServlet("/mysecuredurl") @ServletSecurity(@HttpConstraint(rolesAllowed={"myrole"})) public class MySecuredServlet extends HttpServlet { ... }
This single line of meta-code opens up the magic world of Java EE security, as explained in the following points:
If the user is not authenticated, the web container will ask him/her for his/her credentials; how the user will be asked depends on the configuration of the web application and the kind of client the user is using.
The user agent accepts the credentials and sends that information to the server. The server then tries to validate them using an Authentication Provider. If this is successful, a suitable container for user principals will be created (a Subject), and this will be mapped to the authenticating agent using a sort of session cookie.
Once the user principals are known, they are mapped to the application roles that are declared on the custom deployment descriptors of your application server.
If the servlet needs additional resources or needs to make a call to an EJB method, the security context will be "propagated" (see Java EE 6 specs, v.3.2, at http://www.oracle.com/technetwork/java/javaee/tech/index.html).
Every single step described here involves a bunch of very complex tasks, and all of them are free for the Java EE developer; they are made behind the curtain by the container.
WebLogic security architecture
WebLogic security architecture
is based on a set of classes in the weblogic.security.*
package in the WebLogic Security Framework (WSF), which are used to develop Security Providers that run under the auspices of WebLogic Security Service.
This runtime is the orchestrator that allows application components such as EJBs and servlets to communicate with server resources, with the intermediation of the Security Provider.
Here, we will review some basic concepts of WSF that we need to understand to develop custom providers.
Identifying – Subjects, Principals, and Credentials
WebLogic follows the JAAS architecture of Java SE for its security infrastructure: Subjects, Principals, and Credentials. These are explained as follows:
Subject: Information related to the entity that is requesting the secured resources, such as identities (principal) or attributes (credentials)
Principal: Identity associated with the authenticated entity, such as its full name, the username, a Lightweight Directory Access Protocol (LDAP) group, and everything that identifies it
Credentials: Attributes related to the entity that is authenticated; they may be security-related, such as a Kerberos ticket (
sun.security.krb5.Credentials
) or not security-related, such as attributes that are used by the application
In JAAS, when the login()
method is called on the current LoginContext
class, a new Subject
object is created and the configured LoginModule
is called in sequence to enrich that object with principals.
So, for instance, it is possible to configure a LoginModule
interface that adds Kerberos credentials, another LoginModule
, like WebLogic's UsernamePasswordLoginModule
, that adds PasswordCredential
. These are then used by WebLogic to access restricted resources.
WebLogic resources
Java EE 6 defines the security of components such as an EJB or a connection to an Enterprise Information System (EIS); WebLogic resources extend this level of security. The following is a quote defining resources from the official WebLogic 12c documentation:
A structured object used to represent an underlying WebLogic Server entity that can be protected from unauthorized access.
This means that a DataSource
object can't be accessed directly but only through a JDBCResource
object, and every resource is also represented as a hierarchy; if security is not specified for the leaf, its single parent can be inspected until a suitable configuration is found.
Suppose, for example, the container is checking if the user is allowed to access a certain method of an EJB, whose resource representation is as follows:
type=<ejb>, app=SecuredApp, module=EJBModule, ejb=VeryImportantEJB, method=callItSecure, methodInterface=Home, methodParams={String, int}
If the EJBResource
class can't find a suitable policy for that method, it will ask its parent, the Enterprise Bean, which can verify if the user is allowed or not.
Writing custom providers – MBeans
Java Management Extensions (JMX) is a mandatory part of the Java EE 6 specification that defines standards for the monitoring and management of Enterprise applications in a dynamic and nonintrusive way. Using JMX, it is possible to query an arbitrary application for diagnostic information without knowing anything about the way it is being implemented, but only using a standard tool like JConsole or VisualVM. This is implemented in a structured way, where JMX defines the runtime, the way Management Beans are developed, and how to access that information. Implementation is straightforward; you only need to define what you want to, as follows:
@MXBean public interface MyManagedProperties { public int getCached(); public void callOperation(); }
And the implementation—in Java EE 6 it's really a few lines of code—is as follows:
@Singleton @Startup public class MyManagedPropertiesBean implements MyManagedProperties { private MBeanServer platformMBeanServer; private ObjectName objectName = null; @PostConstruct public void registerInJMX() { try { objectName = new ObjectName("MyMXBean :type=" + this.getClass().getName()); InitialContext ctx = new InitialContext(); platformMBeanServer = (MBeanServer) ctx.lookup("java:comp/env/jmx/runtime"); ctx.close(); platformMBeanServer.registerMBean(this, objectName); } catch (Exception e) { throw new IllegalStateException("Problem during registration of Monitoring into JMX:" + e); } } public int getCached() {//doSomething} public void callOperation() {//doSomething} @PreDestroy public void unregisterFromJMX() { try { platformMBeanServer.unregisterMBean(this.objectName); } catch (Exception e) { throw new IllegalStateException("Problem during unregistration of Monitoring into JMX:" + e); } } }
An MXBean
interface is implemented in the previous code; it is a Managed Bean that can be accessed by a JMX client, which doesn't need to know anything about our application. It is the duty of the agent to convert every domain-specific class to simple properties.
Unfortunately, developing MBeans for WebLogic is not that easy, because of a custom way to generate the MBeans that execute in the MBeanServer
interface. It is necessary to write a custom XML file, called
MBean Definition File (MDF), and then generate a JAR file that can be installed on the WebLogic server using WebLogic's MBeanMaker tool.