Dan Gradl [http://community.jboss.org/people/dgradl] created the discussion
To view the discussion, visit: http://community.jboss.org/message/638433#638433
This is a post in a serious of discussions I am starting to get some discussion going on XACML. I led the implementation of XACML on a large scale using the original SunXACML libraries as the PDP and I am sharing some of my insights as a way to elicit some requirements on the further development of XACML. The original post and index to these discussions is http://community.jboss.org/thread/175091?tstart=0http://community.jboss.org/thread/175091?tstart=0.
In this thread I want to share some thoughts and insights on the topic of performance in XACML and kick off some discussion on this topic. Primarily I'm addressing the PDP component here as it is the most complex runtime component in the XACML logical architecture.
1. Memory utilization
In our application, access control was applied at the field level. Users may be entitled to see data or not see data based on the roles. Whether this much fine-grained control is a good idea or not may be a topic for another discussion. I'm sure that there are applications that will make a similiarly high level of XACML requests. What we observed was that SunXACML created a lot of temporary instances of objects. In other words they were created for the purpose of processing the request and then discarded. The result of this was not running out of memory, but it did cause garbage collection to be run frequently which impacted overall performance. The version we used was a bit older than the one now in JBoss, but I do still see some similar object creation that may be unnecessary for processing. Secondly we made the problem worse by wrappering SunXACML. Our motivation for this was to provide an abstraction layer so that it could be swapped for another PDP in the future. But it actually didn't help that (we piloted using a commercial PDP) every request required creation of a "MyXACMLRequest" and converting it to SunXACMLs. In PicketBox, JBossXACML has a similar function and I'm afraid it may be worse since this is done by a set of JAXB conversions, rather than just a "manual" object mapping. I don't know until some profiling is done, but this is one area of tuning I suggest. But again, I thought the same thing was a good idea, so I'm not critizing the JBossXACML team for it, but we definitely saw this eventually being a bottleneck and removed the abstraction.
2. Execution speed
All of the algorithms in the PDP engine need to be as fast as possible. SunXACML has been around awhile, it was written as one of the first reference implementations of XACML (as far as I know) and I think that a fresh look at it with some XACML learning under the belt would yield better results. However, even if you just stick with the module as is, there were certain aspects such as conditions and functions that could be done more quickly.
3. Policy writing
One of the biggest impacts to performance had to do with how policies are written. The XACML policy model allows you to achieve the same effect multiple different ways, some ways are processed more quickly than others by the SunXACML engine. The targetting also does not do any sort of indexing or caching, so it essentially has to go through all of the policies until it finds a match and depending on the combining algoritm it may stop when it gets to the policy or not. If for example you use a policy permission set (from the RBAC profile) with a set of policy reference ids, and the target matches the last reference in that list it goes through all to reach that (more frequently used resources at the top of the list helped). Another dev team with less experience writing policies wrote a set of terribly inefficient ones that became a huge bottleneck. Anyway, there are a couple opportunities here... one is that you can improve how policies are processed with like a more efficient target matching algorithm or target match caching (already a JIRA task), the other thing is that having a PAP that creates policies for you in the most efficient manner saves a developer having to work out the best way to write the policies each time.
4. Deployment topology
This one is pretty obvious, but the topology of the XACML implementation can influence its performance. You could have a PEP access a remote PDP which has PIPs that access data from other sources (LDAP, RDBMS, etc).
Caching can help in some scenarios see the other discussion forum on this topic.
Reply to this message by going to Community
Start a new discussion in PicketBox Development at Community
Julien Kronegg [http://community.jboss.org/people/jkronegg] modified the document:
"Data Source Configuration in AS 7"
To view the document, visit: http://community.jboss.org/docs/DOC-16657
#Using_DataSourceDefinition_to_configure_a_DataSource Using @DataSourceDefinition to configure a DataSource
#Defining_a_Managed_DataSource Defining a Managed DataSource
#Installing_the_JDBC_Driver Installing the JDBC Driver
#Installing_a_JDBC_driver_as_a_deployment Installing a JDBC driver as a deployment
#Modify_the_JAR Modify the JAR
#Installing_a_JDBC_driver_as_a_module Installing a JDBC driver as a module
#Defining_the_DataSource_itself Defining the DataSource itself
In older versions of the application server, data source configuration was tied to a *-ds.xml file schema that you would deploy in the deploy directory of your configuration. In AS 7, the entire structure of the AS is different, and as you would expect, creating your own data sources is different as well.
h1. Using @DataSourceDefinition to configure a DataSource
Since Java EE6, the new annotation "@DataSourceDefinition" has existed to allow users to configure a data source directly from within their application. (Note that this annotation bypasses the management layer and as such it is recommended only for development and testing purposes.) This annotation requires that a data source implementation class (generally from a JDBC driver JAR) be present on the class path (either by including it in your application, or deploying it as a top-level JAR and referring to it via MANIFEST.MF's Class-Path attribute) and be named explicitly.
h1. Defining a Managed DataSource
In order for a data source to be managed by the application server (and thus take advantage of the management and connection pooling facilities it provides), you must perform two tasks. First, you must make the JDBC driver available to the application server; then you can configure the data source itself. Once you have performed these tasks you can use the data source via standard JNDI injection.
h2. Installing the JDBC Driver
The JDBC driver can be installed into the container in one of two ways: either as a deployment or as a core module. There are pros and cons to each approach, which will be outlined below.
h3. Installing a JDBC driver as a deployment
The recommended way to install a JDBC driver into the application server is to simply deploy it as a regular JAR deployment. The reason for this is that when you run your application server in domain mode, deployments are automatically propagated to all servers to which the deployment applies; thus distribution of the driver JAR is one less thing for administrators to worry about.
cp jdbc.jar <as7>/standalone/deployments
Any JDBC 4-compliant driver will automatically be recognized (JBoss asks the driver if it is Type 4 compliant) and installed into the system by name and version. A JDBC JAR is identified using the Java service provider mechaism. Such JARs will contain a text a file named "META-INF/services/java.sql.Driver", which contains the name of the class(es) of the Drivers which exist in that JAR.
If your JDBC driver JAR is not JDBC 4-compliant, it can be made deployable in one of a few ways.
*Note on MySQL driver and JDBC Type 4 compliance*: while the MySQL driver (at least up to 5.1.18) is designed to be a Type 4 driver, its jdbcCompliant() method always return false. The reason is that the driver does not pass SQL 92 full compliance tests, http://bugs.mysql.com/bug.php?id=62038 says MySQL. Thus, you will need to install the MySQL JDBC driver as a module (see below).
h4. Modify the JAR
The most straightforward solution is to simply modify the JAR and add the missing file. You can do this from your command shell by:
1. Change to, or create, an empty temporary directory.
2. Create a "META-INF" subdirectory.
3. Create a "META-INF/services" subdirectory.
4. Create a "META-INF/services/java.sql.Driver" file which contains one line - the fully-qualified class name of the JDBC driver.
5. Use the "jar" command-line tool to update the JAR like this:
jar -uf jdbc-driver.jar META-INF/services/java.sql.Driver
Please note that you need to correctly setup datasource's driver tag when installing the driver as a deployment (see below in the datasource configuration section).
h3. Installing a JDBC driver as a module
Under the root directory of the application server, is a directory called modules (e.g. jboss-7.0.0.<release>/modules). In this example, I will create the MySQL module in the same tree as the H2 database. The H2 database, which comes preconfigured, like the old DefaultDS with Hypersonic, is under the com/h2database/h2 directory, under the modules directory. So, the first step is to create a directory structure simlar to that for MySQL. I created, under com, a mysql directory, plus a main directory. So, at this point it should like like the following:
Under the main directory, you need to define your module with a module.xml file, and the actual jar file that contains your database driver. In my case, the mysql-connector-java-5.1.15.jar file. This is in contrast to putting the database driver jar file in the old lib directory under your configuration where you deployed your *-ds.xml file. Also, the jar file must have a META-INF/services/java.sql.Driver file. This is due to the way AS 7 will load the driver. Fortunately, the MySQL JDBC driver jar file has this. So, what's the content of the module.xml file.
It's fairly straightforward, and is as follows:
<?xml version="1.0" encoding="UTF-8"?>
~ JBoss, Home of Professional Open Source.
~ Copyright 2010, Red Hat, Inc., and individual contributors
~ as indicated by the @author tags. See the copyright.txt file in the
~ distribution for a full listing of individual contributors.
~ This is free software; you can redistribute it and/or modify it
~ under the terms of the GNU Lesser General Public License as
~ published by the Free Software Foundation; either version 2.1 of
~ the License, or (at your option) any later version.
~ This software is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~ You should have received a copy of the GNU Lesser General Public
~ License along with this software; if not, write to the Free
~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
<module xmlns="urn:jboss:module:1.0" name="com.mysql">
As you can see from above, we give the module name, which in this example is com.mysql, which matches the directory structure we had created under the modules directory.
Besides the module name, we need to tell it where the implementation is, which is the resource-root tag with the path element. In that path element, we simply put the jar name. The path appears to be relative, and default to the main directory under the directory structure you created, which of course is com/mysql in our case.
Finally, you define any dependencies you might have. In this case, as the case with all JDBC data sources, we would be dependent on the Java JDBC API's, which in this case in defined in another module called javax.api, which you can find under modules/javax/api/main as you would expect.
That's really all there is to creating the module, but it will not be started as a service by AS 7, unless its referenced in the configuration. Now, just like everything else in AS 7, configuration is now completely different. There are two main configurations.
h2. Defining the DataSource itself
The first configuration is called domain, and has a domain directory under the root directory of the AS 7 distribution. This is a configuration that is geared toward multiple server instances and multiple server installations. The second is standalone, which is geared for a single instance of the server running on a single server, as you would expect. In regards to data source configuration, there really is no difference, as the datasource schema definition is the same in both cases. So regardless of which one you may be using in your particular case, the configuration is the same. For reference you can see the data source information here:
In either standalone.xml or domain.xml you add the reference to the MySQL module as follows:
<datasource jndi-name="java:jboss/datasources/MySqlDS" pool-name="MySqlDS">
<driver name="com.mysql" module="com.mysql">
The <datasources> tag can contain multiple datasource and XA datasource definitions.They are all included in the one configuration file, either standalone.xml or domain.xml depending on which you are using. In each case the directory structure is as follows:
The other important things to point out, besides the standard JDBC parameters, is the *driver* tag above, and a new section called drivers which is within the "datasources" subsystem in the schema, but below the data sources themselves.
In the *driver* tag above, you should specify the unique name that you gave the driver definition in the *drivers* section.
In case you installed driver as a deployment, the *driver* tag in datasource definition should match the deployment file name.
As you can see, what we put in this is the actual module name we defined in module.xml under jboss-7.0.0.<release>/modules/com/mysql/main/module.xml.
That's all there is to it. The MySQL module is attached as an example.
Comment by going to Community
Create a new document in JBoss AS 7 Development at Community
Daniel Bevenius [http://community.jboss.org/people/beve] created the discussion
"Re: JMS module (HornetQ) can't find my class from WAR"
To view the discussion, visit: http://community.jboss.org/message/635654#635654
I'm not sure I've got the full picture of your application. Does your applications consist on a single war, that is it is both producing messages and consuming messages?
I've seen a similar issue but in my case I had an ear, consisting of a war and an ejb. The war posted a ObjectMessage to a queue that an MDB, located in the ejb, listened to. The Object being posted was located in the war.
When the MDB called objMessage.getObject() I got the following exception:
08:16:27,282 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) javax.jms.JMSException: se.rl.domain.User from [Module "org.hornetq:main" from local module loader @508aeb74 (roots: /work/jboss/as/as7/jboss-as/build/target/jboss-as-7.1.0.Alpha2-SNAPSHOT/modules)]
08:16:27,282 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
08:16:27,283 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:485)
08:16:27,283 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:444)
08:16:27,283 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:421)
08:16:27,284 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:143)
08:16:27,284 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at java.lang.Class.forName0(Native Method)
08:16:27,284 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at java.lang.Class.forName(Class.java:247)
08:16:27,285 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:603)
08:16:27,285 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at org.hornetq.utils.ObjectInputStreamWithClassLoader.resolveClass(ObjectInputStreamWithClassLoader.java:71)
08:16:27,286 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
08:16:27,286 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
08:16:27,286 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
08:16:27,286 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
08:16:27,287 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
08:16:27,287 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at org.hornetq.jms.client.HornetQObjectMessage.getObject(HornetQObjectMessage.java:158)
08:16:27,288 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) at se.rl.migrate.mdb.GreeterMDB.onMessage(GreeterMDB.java:42)
In my case, I was getting this because when trying to locate the class the ThreadContext classloader is first used. The ThreadContext classloader of the mdb module does not have any knowledge of classes in the war, so the code will fallback and try using the 'org.hornetq:main' module and then throw the error displayed above.
I was able to add an explicit dependency from my ejb to my war by adding a manifest header to the ejbs manifest.mf:
This is only for testing and I'd probably extract the objects into a separate jar and add them to the lib directory of the ear.
Not sure if this helps you at all but thought I'd post it just in case.
Reply to this message by going to Community
Start a new discussion in JBoss AS7 Development at Community
Darran Lofthouse [http://community.jboss.org/people/dlofthouse] modified the document:
"AS 7.1.0 Beta1 - Security Enabled By Default"
To view the document, visit: http://community.jboss.org/docs/DOC-17367
h1. AS 7.1.0 Beta1 - Security Enabled By Default
Starting from the 7.1.0.Beta1 release we now have security enabled by default on the AS 7.1 distribution, the objective that we have been trying to achieve is to deliver an application server distribution where the management interfaces are secured by default to prevent unauthorized remote access whilst still allowing access for local users for an easier out of the box experience.
h2. The Default Realm
The distribution exposes two management interfaces by default, one for HTTP access and one for Native access - both of these are secured using the same realm called 'ManagementRealm'.
The management realm is backed by a properties file used to store the users, the properties file is called 'mgmt-users.properties' and is stored in the configuration folder, depending on the mode you are running this will be one of the following: -
The mgmt-users.properties file is monitored for updates at runtime so additions and removals from this file will be detected.
For authentication at the transport level we make use of Digest authentication, for this reason in the properties file instead of holding a plain text password we hold a hex encoded hash that consists of the username, the name of the realm, and the password.
Despite hashed the contents of the file should still be considered sensitive and should be protected, the advantage of the hash is that it does make the contents specific to the realm in use and not applicable to different realms.
The users defined in this realm are used for the authentication of remote clients, for the definition of remote clients all HTTP access is considered remote so to make use of the admin console a user will need to be defined - tools such as the CLI will be able to make use of a local mechanism described below.
h3. Adding New Users
To add new users to the properties file we now provide a utility to handle this, the utility can be triggered by running the add-user.sh or add-user.bat scripts in the bin folder of the AS 7.1 installation, this will trigger the following wizard: -
This utility requires three pieces of information for the new user: -
* Realm - this is the name of the realm used to secure the management interfaces, by default it is 'ManagementRealm' so you can just press enter, if you change the realm as described below this is where you need to enter your new realm name.
* Username - the username needs to be alpha numeric.
* Password - At the moment the main restriction on this field is that is can not be the same as the username.
As you can see from the output this will automatically update both of the properties files in the installation.
As a convenience the add-user.sh and add-user.bat scripts can take the username, password and realm in as command line parameters and the tool will then update the files non-interactively - however this is not recommended on shared systems as anyone inspecting running processes could see the plain text passwords.
If you are going to use this convenience approach the command syntax is: -
./add-user.sh username password
./add-user.sh username password realm
h3. Generating the Hash
If you already have a database of users with their plain text passwords stored then you may like to generate the properties files youself - to generate the hashes you can make use of a utility class that we use ourselves.
The class is called 'org.jboss.sasl.util.UsernamePasswordHashUtil' and is within the 'org.jboss.sasl:jboss-sasl' maven artefact or the org/jboss/sasl module included with the AS distribution.
Using the above class the hex encoded hash can be generated as: -
String hash = new UsernamePasswordHashUtil().generateHashedHexURP(userName, realm, password);
This hash can then be appended to the properties file in the format username=hash
+The reason an instance of UsernamePasswordHashUtil is used is because a MessageDigest is cached and can be used for subsequent generate requests.+
h2. Local Clients
After protecting the server from remote unauthorized access the next issue is providing the local user running the server access using tools such as the CLI, the Maven plug-in, JBoss Tools etc... without forcing the use of a username and password in this scenario. For this case the user running the server would already have access to the configuration and could add their own user or disable the security checks so mandating that they enter a username and password is just complicating the local users experience.
For this scenario we have added a new SASL mechanism that is used internally by our client APIs, when this mechanism is selected the following sequence is followed to authenticate the user: -
1. Client sends message to server saying "I want to use the JBoss Local User SASL mechanism"
2. Server generates one time token, writes it to a unique file and sends message to client with full path of the file.
3. Client reads the token from the file and sends it to the server.
4. Server verifies token received and deletes the file.
This token is generated within the AS installation folder so for this mechanism to pass the client has demonstrated to the server that is both on the same host and that it has access to AS installation.
When deciding to implement this mechanism we did consider if we should just allow unauthenticated access to all local users, however on a multi-user system this could mean other users not intended to access the AS management would have access - with this mechanism in place those other users would not by default have access to the generated tokens.
h2. Enhancing Security
As described above the contents of the property files make use of a hex encoded hash of the username, realm and password - to further enhance security it is recommended that you also change the name of the default realm to something else.
*Note: As the hash is realm specific this change will need to be made BEFORE you add any users, changing the realm name will invalidate the contents of the property files.*
To change the name of the realm edit either the standalone.xml or host.xml (as applicable) and change the following attributes: -
Where the actual is realm is defined the name will need to be changed.
Each of the management interfaces will need to be updated to reference the new realm name.
When using the command line ad-user.sh or add-user.bat scripts you will now need to enter the name of the new realm in response to the first question.
Comment by going to Community
Create a new document in JBoss AS 7 Development at Community
ronorato [http://community.jboss.org/people/ronorato] created the discussion
"JMS Classload issue"
To view the discussion, visit: http://community.jboss.org/message/637558#637558
I have been attempting to make use of HornetQ in my application but am having little success getting it to work. A bit on my environment; I am running JBoss AS 7 (7.0.2). I have both Windows and Linux environments that I have tested on, both fail. My application is composed of EJBs, a few common jar files and a single WAR all packaged into a single ear. The classes that are to be serialized onto a HornetQ topic are stored in a standard jar file that is placed in the lib directory of the ear.
Now onto the problem. My Web application is publishing an event onto a HornetQ topic which my EJB is listening on (I am not using MDBs). I am able to publish successfully to the topic and it appears that the message is being read from the topic by the subscriber. The problem comes when my code hits the following line "java.io.Serializable obj = ((ObjectMessage)message).getObject();". This line of code produces the following exception:
(Thread-3 (group:HornetQ-client-global-threads-33253167)) on Message failed with exception: com.test.event.EventMessage from [Module "org.hornetq:main" from local module loader @12a3793 (roots: c:\JBoss-as\modules)]
Any help resolving this problem would be greatly appreciated.
Reply to this message by going to Community
Start a new discussion in JBoss AS 7 Development at Community