This closes #85 - work on jaas

This commit is contained in:
Clebert Suconic 2015-02-02 14:18:30 -05:00
commit 58cc025653
13 changed files with 29 additions and 1226 deletions

View File

@ -89,7 +89,6 @@
<li><a href="examples/jms/http-transport/readme.html">JMS HTTP Example</a></li>
<li><a href="examples/jms/instantiate-connection-factory/readme.html">JMS Instantiate Connection Factory Example</a></li>
<li><a href="examples/jms/interceptor/readme.html">JMS Interceptor Example</a></li>
<li><a href="examples/jms/jaas/readme.html">JAAS Example</a></li>
<li><a href="examples/jms/jms-auto-closeable/readme.html">JMS Auto Closable Example</a></li>
<li><a href="examples/jms/jms-bridge/readme.html">JMS Bridge Example</a></li>
<li><a href="examples/jms/jms-completion-listener/readme.html">JMS Completion Listener Example</a></li>
@ -150,7 +149,6 @@
<li><a href="examples/jms/xa-heuristic/readme.html">JMS XA Heuristic Example</a></li>
<li><a href="examples/jms/xa-receive/readme.html">JMS XA Receive Example</a></li>
<li><a href="examples/jms/xa-send/readme.html">JMS XA Send Example</a></li>
<li><a href="examples/jms/xa-with-jta/readme.html">JMS XA with JTA Example</a></li>
</ol>
</ul>
</ul>

View File

@ -54,7 +54,7 @@ specified. If the user has any of those roles, he/she will be granted
that permission for that set of addresses.
Let's take a simple example, here's a security block from
`activemq-configuration.xml` or `activemq-queues.xml` file:
`activemq-configuration.xml` file:
<security-setting match="globalqueues.europe.#">
<permission type="createDurableQueue" roles="admin"/>
@ -67,7 +67,7 @@ Let's take a simple example, here's a security block from
The '`#`' character signifies "any sequence of words". Words are
delimited by the '`.`' character. For a full description of the wildcard
syntax please see [Understanding the HornetQ Wildcard Syntax](wildcard-syntax.md).
syntax please see [Understanding the HornetQ Wildcard Syntax](wildcard-syntax.md).
The above security block applies to any address
that starts with the string "globalqueues.europe.":
@ -132,159 +132,45 @@ For more information on configuring the SSL transport, please see [Configuring t
## Basic user credentials
ActiveMQ ships with a security manager implementation that reads user
credentials, i.e. user names, passwords and role information from an xml
file on the classpath called `activemq-users.xml`. This is the default
security manager.
credentials, i.e. user names, passwords and role information from properties
files on the classpath called `activemq-users.properties` and `activemq-roles.properties`. This is the default security manager.
If you wish to use this security manager, then users, passwords and
roles can easily be added into this file.
roles can easily be added into these files.
Let's take a look at an example file:
To configure this manager then it needs to be added to the `bootstrap.xml` configuration.
Lets take a look at what this might look like:
<configuration xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq ../schemas/activemq-users.xsd ">
<basic-security>
<users>file:${activemq.home}/config/non-clustered/activemq-users.properties</users>
<roles>file:${activemq.home}/config/non-clustered/activemq-roles.properties</roles>
<default-user>guest</default-user>
</basic-security>
<defaultuser name="guest" password="guest">
<role name="guest"/>
</defaultuser>
The first 2 elements `users` and `roles` define what properties files should be used to load in the users and passwords.
<user name="tim" password="marmite">
<role name="admin"/>
</user>
<user name="andy" password="doner_kebab">
<role name="admin"/>
<role name="guest"/>
</user>
<user name="jeff" password="camembert">
<role name="europe-users"/>
<role name="guest"/>
</user>
</configuration>
The first thing to note is the element `defaultuser`. This defines what
The next thing to note is the element `defaultuser`. This defines what
user will be assumed when the client does not specify a
username/password when creating a session. In this case they will be the
user `guest` and have the role also called `guest`. Multiple roles can
be specified for a default user.
user `guest`. Multiple roles can be specified for a default user in the
`activemq-roles.properties`.
We then have three more users, the user `tim` has the role `admin`. The
user `andy` has the roles `admin` and `guest`, and the user `jeff` has
the roles `europe-users` and `guest`.
Lets now take alook at the `activemq-users.properties` file, this is basically
just a set of key value pairs that define the users and their password, like so:
## Changing the security manager
bill=activemq
andrew=activemq1
frank=activemq2
sam=activemq3
If you do not want to use the default security manager then you can
specify a different one by editing the file `activemq-beans.xml` (or
`activemq-jboss-beans.xml` if you're running JBoss Application Server)
and changing the class for the `ActiveMQSecurityManager` bean.
The `activemq-roles.properties` defines what groups these users belong too
where the key is the user and the value is a comma seperated list of the groups
the user belongs to, like so:
Let's take a look at a snippet from the default beans file:
<bean name="ActiveMQSecurityManager" class="org.apache.activemq.spi.core.security.ActiveMQSecurityManagerImpl">
<start ignored="true"/>
<stop ignored="true"/>
</bean>
The class
`org.apache.activemq.spi.core.security.ActiveMQSecurityManagerImpl` is
the default security manager that is used by the standalone server.
ActiveMQ ships with two other security manager implementations you can
use off-the-shelf; one a JAAS security manager and another for
integrating with JBoss Application Sever security, alternatively you
could write your own implementation by implementing the
`org.apache.activemq.spi.core.security.ActiveMQSecurityManager`
interface, and specifying the classname of your implementation in the
file `activemq-beans.xml` (or `activemq-jboss-beans.xml` if you're
running JBoss Application Server).
These two implementations are discussed in the next two sections.
## JAAS Security Manager
JAAS stands for 'Java Authentication and Authorization Service' and is a
standard part of the Java platform. It provides a common API for
security authentication and authorization, allowing you to plugin your
pre-built implementations.
To configure the JAAS security manager to work with your pre-built JAAS
infrastructure you need to specify the security manager as a
`JAASSecurityManager` in the beans file. Here's an example:
<bean name="ActiveMQSecurityManager" class="org.apache.activemq.integration.jboss.security.JAASSecurityManager">
<start ignored="true"/>
<stop ignored="true"/>
<property name="ConfigurationName">org.apache.activemq.jms.example.ExampleLoginModule</property>
<property name="Configuration">
<inject bean="ExampleConfiguration"/>
</property>
<property name="CallbackHandler">
<inject bean="ExampleCallbackHandler"/>
</property>
</bean>
Note that you need to feed the JAAS security manager with three
properties:
- ConfigurationName: the name of the `LoginModule` implementation that
JAAS must use
- Configuration: the `Configuration` implementation used by JAAS
- CallbackHandler: the `CallbackHandler` implementation to use if user
interaction are required
## Example
See ? for an example which shows how ActiveMQ can be configured to use
JAAS.
## JBoss AS Security Manager
The JBoss AS security manager is used when running ActiveMQ inside the
JBoss Application server. This allows tight integration with the JBoss
Application Server's security model.
The class name of this security manager is
`org.apache.activemq.integration.jboss.security.JBossASSecurityManager`
Take a look at one of the default `activemq-jboss-beans.xml` files for
JBoss Application Server that are bundled in the distribution for an
example of how this is configured.
### Configuring Client Login
JBoss can be configured to allow client login, basically this is when a
JEE component such as a Servlet or EJB sets security credentials on the
current security context and these are used throughout the call. If you
would like these credentials to be used by ActiveMQ when sending or
consuming messages then set `allowClientLogin` to true. This will bypass
ActiveMQ authentication and propagate the provided Security Context. If
you would like ActiveMQ to authenticate using the propagated security
then set the `authoriseOnClientLogin` to true also.
There is more info on using the JBoss client login module
[here](http://community.jboss.org/wiki/ClientLoginModule)
> **Note**
>
> If messages are sent non blocking then there is a chance that these
> could arrive on the server after the calling thread has completed
> meaning that the security context has been cleared. If this is the
> case then messages will need to be sent blocking
### Changing the Security Domain
The name of the security domain used by the JBoss AS security manager
defaults to `java:/jaas/activemq
`. This can be changed by specifying `securityDomainName`
(e.g. java:/jaas/myDomain).
bill=user
andrew=europe-user,user
frank=us-user,news-user,user
sam=news-user,user
## Changing the username/password for clustering

View File

@ -1,153 +0,0 @@
<?xml version='1.0'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.activemq.examples.jms</groupId>
<artifactId>jms-examples</artifactId>
<version>6.0.0-SNAPSHOT</version>
</parent>
<artifactId>activemq-jms-jaas-example</artifactId>
<packaging>jar</packaging>
<name>ActiveMQ6 JMS "JAAS" Example</name>
<dependencies>
<dependency>
<groupId>org.apache.activemq.examples.jms</groupId>
<artifactId>activemq-jms-examples-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-maven-plugin</artifactId>
<executions>
<execution>
<id>start</id>
<goals>
<goal>start</goal>
</goals>
<configuration>
<securityManager implementation="org.apache.activemq.spi.core.security.JAASSecurityManager">
<configurationName>org.apache.activemq.jms.example.ExampleLoginModule</configurationName>
<callbackHandler implementation="org.apache.activemq.jms.example.ExampleCallbackHandler"/>
<config implementation="org.apache.activemq.jms.example.ExampleConfiguration">
<loginModuleName>org.apache.activemq.jms.example.ExampleLoginModule</loginModuleName>
<options>
<user>jboss</user>
<pass>redhat</pass>
<role>guest</role>
</options>
</config>
</securityManager>
<systemProperties>
<property>
<name>build.directory</name>
<value>${basedir}/target/</value>
</property>
</systemProperties>
</configuration>
</execution>
<execution>
<id>runClient</id>
<goals>
<goal>runClient</goal>
</goals>
<configuration>
<clientClass>org.apache.activemq.jms.example.JAASExample</clientClass>
<args>
<param>tcp://localhost:5445</param>
</args>
</configuration>
</execution>
<execution>
<id>stop</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.activemq.examples.jms</groupId>
<artifactId>activemq-jms-jaas-example</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jms-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-jms-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jms_2.0_spec</artifactId>
<version>${geronimo.jms.2.spec.version}</version>
</dependency>
</dependencies>
<configuration>
<waitOnStart>false</waitOnStart>
<configurationDir>${basedir}/target/classes/activemq/server0</configurationDir>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,117 +0,0 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<html>
<head>
<title>ActiveMQ JAAS Example</title>
<link rel="stylesheet" type="text/css" href="../common/common.css" />
<link rel="stylesheet" type="text/css" href="../common/prettify.css" />
<script type="text/javascript" src="../common/prettify.js"></script>
</head>
<body onload="prettyPrint()">
<h1>JAAS Example</h1>
<p>This example shows you how to configure ActiveMQ to use JAAS for security.</p>
<p>ActiveMQ can leverage JAAS to delegate user authentication and authorization to existing security infrastructure.</p>
<p>
The example will show how to configure ActiveMQ with JAAS in <a href="server0/activemq-beans.xml">activemq-beans.xml</a>
(You would use <literal>activemq-jboss-beans.xml</literal> if you are running inside JBoss Application
Server).
It will use a simple <code>LoginModule</code> without any user interaction.
The example will create a connection and authenticate the user with this JAAS LoginModule, send a message
to a queue and receive it (see the <a href="../../queue/readme.html">Queue example</a> for a complete description
of the application code)
</p>
<p>Note than the example actually sets the security manager via the maven pom.xml, however for we will discuss as if
the activemq-beans.xml is being configured, the example beans file can be found under the <code>src/main/resources</code>
directory</p>
<h2>Example setup</h2>
<p>ActiveMQ can use a JAAS security manager by specifying it in <a href="server0/activemq-beans.xml">activemq-beans.xml</a>:</p>
<pre class="prettyprint">
&lt;!-- The security manager using JAAS --&gt;
&lt;bean name=&quot;ActiveMQSecurityManager&quot; class=&quot;org.apache.activemq.integration.jboss.security.JAASSecurityManager&quot;&gt;
&lt;property name=&quot;configurationName&quot;&gt;org.apache.activemq.jms.example.ExampleLoginModule&lt;/property&gt;
&lt;property name=&quot;configuration&quot;&gt;
&lt;inject bean=&quot;ExampleConfiguration&quot;/&gt;
&lt;/property&gt;
&lt;property name=&quot;callbackHandler&quot;&gt;
&lt;inject bean=&quot;ExampleCallbackHandler&quot; /&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;!-- JAAS uses a simple LoginModule where the user credentials and roles are
specified as options in the constructor --&gt;
&lt;bean name=&quot;ExampleConfiguration&quot; class=&quot;org.apache.activemq.jms.example.ExampleConfiguration&quot;&gt;
&lt;constructor&gt;
&lt;parameter&gt;org.apache.activemq.jms.example.ExampleLoginModule&lt;/parameter&gt;
&lt;parameter&gt;
&lt;map class=&quot;java.util.HashMap&quot; keyClass=&quot;java.lang.String&quot;
valueClass=&quot;java.lang.String&quot;&gt;
&lt;entry&gt;
&lt;key&gt;user&lt;/key&gt;
&lt;value&gt;jboss&lt;/value&gt;
&lt;/entry&gt;
&lt;entry&gt;
&lt;key&gt;pass&lt;/key&gt;
&lt;value&gt;redhat&lt;/value&gt;
&lt;/entry&gt;
&lt;entry&gt;
&lt;key&gt;role&lt;/key&gt;
&lt;value&gt;guest&lt;/value&gt;
&lt;/entry&gt;
&lt;/map&gt;
&lt;/parameter&gt;
&lt;/constructor&gt;
&lt;/bean&gt;
&lt;!-- the CallbackHandler does nothing as we don&apos;t have any user interaction --&gt;
&lt;bean name=&quot;ExampleCallbackHandler&quot; class=&quot;org.apache.activemq.jms.example.ExampleCallbackHandler&quot;
/&gt;
</pre>
<ul>
<li>the ActiveMQSecurityManager's <code>configurationName</code> must be the name of the Java class implementing <code>LoginModule</code></li>
<li>the <code>callbackHandler</code> property must be an implementation of <code>CallbackHandler</code>. In this example, the ExampleCallbackHandler
does nothing since the authentication requires no user interaction</li>
<li>the <code>configuration</code> property must be an implementation of <code>Configuration</code>. For simplicity, we pass directly the
user credentials as options to the <code>ExampleConfiguration</code> constructor. These options will be passed to an instance
of ExampleLoginModule which will check that the only valid user is "jboss" with the password "redhat"
and it has the role "guest". </li>
</ul>
<h2>Example step-by-step</h2>
<p><i>To run the example, simply type <code>mvn verify</code> from this directory</i></p>
<p>The only relevant step with regard to JAAS configuration is step 4 (all the other
steps are identical to the <a href="../../queue/readme.html">Queue example</a>).
<ol start="4">
<li>We create a JMS Connection with user "jboss" and password "redhat". Any other
combination of name and password won't be valid for the ExampleLoginModule</li>
<pre class="prettyprint">
<code>connection = cf.createConnection("jboss", "redhat");</code>
</pre>
</ol>
<h2>More information</h2>
<ul>
<li>User Manual's <a href="../../../docs/user-manual/en/html_single/index.html#security">Security chapter</a></li>
</ul>
</body>
</html>

View File

@ -1,38 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.jms.example;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
/**
* A ExampleCallbackHandler
*
* @author <a href="mailto:jmesnil@redhat.com">Jeff Mesnil</a>
*/
public class ExampleCallbackHandler implements CallbackHandler
{
public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
// do nothing, authentication is done
// by passing credentials directly to the ExampleLoginModule
}
}

View File

@ -1,58 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.jms.example;
import java.util.Map;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
/**
* A ExampleConfiguration
*
* @author <a href="mailto:jmesnil@redhat.com">Jeff Mesnil</a>
*/
public class ExampleConfiguration extends Configuration
{
private Map<String, ?> options;
private String loginModuleName;
public ExampleConfiguration()
{
}
public ExampleConfiguration(final String loginModuleName, final Map<String, ?> options)
{
this.loginModuleName = loginModuleName;
this.options = options;
}
@Override
public AppConfigurationEntry[] getAppConfigurationEntry(final String name)
{
AppConfigurationEntry entry = new AppConfigurationEntry(loginModuleName,
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
options);
return new AppConfigurationEntry[] { entry };
}
@Override
public void refresh()
{
}
}

View File

@ -1,142 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.jms.example;
import java.security.Principal;
import java.security.acl.Group;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import org.apache.activemq.spi.core.security.JAASSecurityManager;
/**
* A ExampleLoginModule
*
* @author <a href="mailto:jmesnil@redhat.com">Jeff Mesnil</a>
*/
public class ExampleLoginModule implements LoginModule
{
private Map<String, ?> options;
private Subject subject;
public ExampleLoginModule()
{
}
public boolean abort() throws LoginException
{
return true;
}
public boolean commit() throws LoginException
{
return true;
}
public void initialize(final Subject subject,
final CallbackHandler callbackHandler,
final Map<String, ?> sharedState,
final Map<String, ?> options)
{
this.subject = subject;
// the credentials are passed directly to the
// login module through the options user, pass, role
this.options = options;
}
public boolean login() throws LoginException
{
Iterator<char[]> iterator = subject.getPrivateCredentials(char[].class).iterator();
char[] passwordChars = iterator.next();
String password = new String(passwordChars);
Iterator<Principal> iterator2 = subject.getPrincipals().iterator();
System.out.println("subject = " + subject);
String user = iterator2.next().getName();
boolean authenticated = user.equals(options.get("user")) && password.equals(options.get("pass"));
if (authenticated)
{
Group roles = new SimpleGroup("Roles");
roles.addMember(new JAASSecurityManager.SimplePrincipal((String)options.get("role")));
subject.getPrincipals().add(roles);
}
System.out.format("JAAS authentication >>> user=%s, password=%s\n", user, password);
System.out.println("authenticated = " + authenticated);
return authenticated;
}
public Subject getSubject()
{
return subject;
}
public boolean logout() throws LoginException
{
return true;
}
public class SimpleGroup implements Group
{
private final String name;
private final Set<Principal> members = new HashSet<Principal>();
public SimpleGroup(final String name)
{
this.name = name;
}
public boolean addMember(final Principal principal)
{
return members.add(principal);
}
public boolean isMember(final Principal principal)
{
return members.contains(principal);
}
public Enumeration<? extends Principal> members()
{
return Collections.enumeration(members);
}
public boolean removeMember(final Principal principal)
{
return members.remove(principal);
}
public String getName()
{
return name;
}
}
}

View File

@ -1,103 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.jms.example;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import org.apache.activemq.common.example.ActiveMQExample;
/**
* A simple JMS Queue example that creates a producer and consumer on a queue and sends then receives a message.
* The ActiveMQ server is configured to use JAAS.
*
* @author <a href="mailto:jmesnil@redhat.com">Jeff Mesnil</a>
*/
public class JAASExample extends ActiveMQExample
{
public static void main(final String[] args)
{
new JAASExample().run(args);
}
@Override
public boolean runExample() throws Exception
{
Connection connection = null;
InitialContext initialContext = null;
try
{
// Step 1. Create an initial context to perform the JNDI lookup.
initialContext = new InitialContext();
// Step 2. Perfom a lookup on the queue
Queue queue = (Queue)initialContext.lookup("queue/exampleQueue");
// Step 3. Perform a lookup on the Connection Factory
ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("ConnectionFactory");
// Step 4.Create a JMS Connection with user "jboss" and password "redhat"
connection = cf.createConnection("jboss", "redhat");
// Step 5. Create a JMS Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Step 6. Create a JMS Message Producer
MessageProducer producer = session.createProducer(queue);
// Step 7. Create a Text Message
TextMessage message = session.createTextMessage("This is a text message");
System.out.println("Sent message: " + message.getText());
// Step 8. Send the Message
producer.send(message);
// Step 9. Create a JMS Message Consumer
MessageConsumer messageConsumer = session.createConsumer(queue);
// Step 10. Start the Connection
connection.start();
// Step 11. Receive the message
TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);
System.out.println("Received message: " + messageReceived.getText());
return true;
}
finally
{
// Step 12. Be sure to close our JMS resources!
if (initialContext != null)
{
initialContext.close();
}
if (connection != null)
{
connection.close();
}
}
}
}

View File

@ -1,62 +0,0 @@
<?xml version='1.0'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:activemq"
xsi:schemaLocation="urn:activemq /schema/activemq-server.xsd">
<jms xmlns="urn:activemq:jms">
<!--the queue used by the example-->
<queue name="exampleQueue"/>
</jms>
<core xmlns="urn:activemq:core">
<bindings-directory>${build.directory}/server0/data/messaging/bindings</bindings-directory>
<journal-directory>${build.directory}/server0/data/messaging/journal</journal-directory>
<large-messages-directory>${build.directory}/server0/data/messaging/largemessages</large-messages-directory>
<paging-directory>${build.directory}/server0/data/messaging/paging</paging-directory>
<!-- Acceptors -->
<acceptors>
<acceptor name="netty-acceptor">
<factory-class>org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>
</acceptor>
</acceptors>
<!-- Other config -->
<security-settings>
<!--security for example queue-->
<security-setting match="jms.queue.exampleQueue">
<permission type="createDurableQueue" roles="guest"/>
<permission type="deleteDurableQueue" roles="guest"/>
<permission type="createNonDurableQueue" roles="guest"/>
<permission type="deleteNonDurableQueue" roles="guest"/>
<permission type="consume" roles="guest"/>
<permission type="send" roles="guest"/>
</security-setting>
</security-settings>
</core>
</configuration>

View File

@ -1,20 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://localhost:5445
queue.queue/exampleQueue=exampleQueue

View File

@ -78,8 +78,6 @@ under the License.
<module>http-transport</module>
<module>interceptor</module>
<module>instantiate-connection-factory</module>
<!--todo reenable once the HQ plugin v1.1.0 is available-->
<!--<module>jaas</module>-->
<module>jms-bridge</module>
<module>jmx</module>
<module>large-message</module>

View File

@ -16,20 +16,9 @@
*/
package org.apache.activemq.tests.integration.security;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.io.IOException;
import java.security.acl.Group;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.api.core.ActiveMQException;
@ -47,10 +36,8 @@ import org.apache.activemq.core.server.ActiveMQServer;
import org.apache.activemq.core.server.Queue;
import org.apache.activemq.core.settings.HierarchicalRepository;
import org.apache.activemq.spi.core.security.ActiveMQSecurityManagerImpl;
import org.apache.activemq.spi.core.security.JAASSecurityManager;
import org.apache.activemq.tests.util.CreateMessage;
import org.apache.activemq.tests.util.ServiceTestBase;
import org.jboss.security.SimpleGroup;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -894,85 +881,6 @@ public class SecurityTest extends ServiceTestBase
}
/*
* basic JAAS tests
*/
@Test
public void testJaasCreateSessionSucceeds() throws Exception
{
String domainName = SimpleLogingModule.class.getName();
Configuration configuration = createDefaultConfig(false)
.setSecurityEnabled(true);
JAASSecurityManager securityManager = new JAASSecurityManager();
ActiveMQServer server = createServer(false, configuration, securityManager);
securityManager.setConfigurationName(domainName);
securityManager.setCallbackHandler(new CallbackHandler()
{
public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
// empty callback, auth info are directly passed as options to the login module
}
});
Map<String, Object> options = new HashMap<String, Object>();
options.put("authenticated", Boolean.TRUE);
securityManager.setConfiguration(new SimpleConfiguration(domainName, options));
server.start();
ClientSessionFactory cf = createSessionFactory(locator);
try
{
ClientSession session = cf.createSession(false, true, true);
session.close();
}
catch (ActiveMQException e)
{
Assert.fail("should not throw exception");
}
}
@Test
public void testJaasCreateSessionFails() throws Exception
{
String domainName = SimpleLogingModule.class.getName();
Configuration configuration = createDefaultConfig(false)
.setSecurityEnabled(true);
JAASSecurityManager securityManager = new JAASSecurityManager();
ActiveMQServer server = createServer(false, configuration, securityManager);
securityManager.setConfigurationName(domainName);
securityManager.setCallbackHandler(new CallbackHandler()
{
public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
// empty callback, auth info are directly passed as options to the login module
}
});
Map<String, Object> options = new HashMap<String, Object>();
options.put("authenticated", Boolean.FALSE);
securityManager.setConfiguration(new SimpleConfiguration(domainName, options));
server.start();
ClientSessionFactory cf = createSessionFactory(locator);
try
{
cf.createSession(false, true, true);
Assert.fail("should not throw exception");
}
catch (ActiveMQSecurityException se)
{
//ok
}
catch (ActiveMQException e)
{
fail("Invalid Exception type:" + e.getType());
}
}
@Test
public void testComplexRoles() throws Exception
{
@ -1352,82 +1260,4 @@ public class SecurityTest extends ServiceTestBase
fail("Invalid Exception type:" + e.getType());
}
}
public static class SimpleLogingModule implements LoginModule
{
private Map<String, ?> options;
private Subject subject;
public SimpleLogingModule()
{
}
public boolean abort() throws LoginException
{
return true;
}
public boolean commit() throws LoginException
{
return true;
}
public void initialize(final Subject subject, final CallbackHandler callbackHandler,
final Map<String, ?> sharedState, final Map<String, ?> options)
{
this.subject = subject;
this.options = options;
}
public boolean login() throws LoginException
{
boolean authenticated = (Boolean) options.get("authenticated");
if (authenticated)
{
Group roles = new SimpleGroup("Roles");
roles.addMember(new JAASSecurityManager.SimplePrincipal((String) options.get("role")));
subject.getPrincipals().add(roles);
}
return authenticated;
}
public Subject getSubject()
{
return subject;
}
public boolean logout() throws LoginException
{
return true;
}
}
public static class SimpleConfiguration extends javax.security.auth.login.Configuration
{
private final Map<String, ?> options;
private final String loginModuleName;
public SimpleConfiguration(final String loginModuleName, final Map<String, ?> options)
{
this.loginModuleName = loginModuleName;
this.options = options;
}
@Override
public AppConfigurationEntry[] getAppConfigurationEntry(final String name)
{
AppConfigurationEntry entry =
new AppConfigurationEntry(loginModuleName, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
options);
return new AppConfigurationEntry[]{entry};
}
@Override
public void refresh()
{
}
}
}

View File

@ -1,216 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.tests.unit.core.security.impl;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import java.io.IOException;
import java.security.Principal;
import java.security.acl.Group;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.core.security.CheckType;
import org.apache.activemq.core.security.Role;
import org.apache.activemq.spi.core.security.JAASSecurityManager;
import org.apache.activemq.tests.util.UnitTestCase;
import org.jboss.security.SimpleGroup;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* tests the JAASSecurityManager
*
* @author <a href="jmesnil@redhat.com">Jeff Mesnil</a>
*/
public class JAASSecurityManagerTest extends UnitTestCase
{
private JAASSecurityManager securityManager;
private static final String USER = "user";
private static final String PASSWORD = "password";
private static final String INVALID_PASSWORD = "invalidPassword";
private static final String ROLE = "role";
private static final String INVALID_ROLE = "invalidRole";
@Override
@Before
public void setUp() throws Exception
{
super.setUp();
securityManager = new JAASSecurityManager();
final String domainName = SimpleLogingModule.class.getName();
// pass the correct user/pass and a role as options to the login module
final Map<String, String> options = new HashMap<String, String>();
options.put("user", JAASSecurityManagerTest.USER);
options.put("pass", JAASSecurityManagerTest.PASSWORD);
options.put("role", JAASSecurityManagerTest.ROLE);
securityManager.setConfigurationName(domainName);
securityManager.setCallbackHandler(new CallbackHandler()
{
public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
// empty callback, auth info are directly passed as options to the login module
}
});
securityManager.setConfiguration(new SimpleConfiguration(domainName, options));
}
@Override
@After
public void tearDown() throws Exception
{
securityManager = null;
super.tearDown();
}
@Test
public void testValidatingUser()
{
Assert.assertTrue(securityManager.validateUser(JAASSecurityManagerTest.USER, JAASSecurityManagerTest.PASSWORD));
Assert.assertFalse(securityManager.validateUser(JAASSecurityManagerTest.USER,
JAASSecurityManagerTest.INVALID_PASSWORD));
}
@Test
public void testValidatingUserAndRole()
{
Set<Role> roles = new HashSet<Role>();
roles.add(new Role(JAASSecurityManagerTest.ROLE, true, true, true, true, true, true, true));
Assert.assertTrue(securityManager.validateUserAndRole(JAASSecurityManagerTest.USER,
JAASSecurityManagerTest.PASSWORD,
roles,
CheckType.CREATE_DURABLE_QUEUE));
roles.clear();
roles.add(new Role(JAASSecurityManagerTest.INVALID_ROLE, true, true, true, true, true, true, true));
Assert.assertFalse(securityManager.validateUserAndRole(JAASSecurityManagerTest.USER,
JAASSecurityManagerTest.PASSWORD,
roles,
CheckType.CREATE_DURABLE_QUEUE));
}
public static class SimpleLogingModule implements LoginModule
{
private Map<String, ?> options;
private Subject subject;
public SimpleLogingModule()
{
}
public boolean abort() throws LoginException
{
return true;
}
public boolean commit() throws LoginException
{
return true;
}
public void initialize(final Subject subject,
final CallbackHandler callbackHandler,
final Map<String, ?> sharedState,
final Map<String, ?> options)
{
this.subject = subject;
this.options = options;
}
public boolean login() throws LoginException
{
Iterator<char[]> iterator = subject.getPrivateCredentials(char[].class).iterator();
char[] passwordChars = iterator.next();
String password = new String(passwordChars);
Iterator<Principal> iterator2 = subject.getPrincipals().iterator();
String user = iterator2.next().getName();
boolean authenticated = user.equals(options.get("user")) && password.equals(options.get("pass"));
if (authenticated)
{
Group roles = new SimpleGroup("Roles");
roles.addMember(new JAASSecurityManager.SimplePrincipal((String) options.get("role")));
subject.getPrincipals().add(roles);
}
return authenticated;
}
public Subject getSubject()
{
return subject;
}
public boolean logout() throws LoginException
{
return true;
}
}
public static class SimpleConfiguration extends Configuration
{
private final Map<String, ?> options;
private final String loginModuleName;
public SimpleConfiguration(final String loginModuleName, final Map<String, ?> options)
{
this.loginModuleName = loginModuleName;
this.options = options;
}
@Override
public AppConfigurationEntry[] getAppConfigurationEntry(final String name)
{
AppConfigurationEntry entry = new AppConfigurationEntry(loginModuleName,
LoginModuleControlFlag.REQUIRED,
options);
return new AppConfigurationEntry[]{entry};
}
@Override
public void refresh()
{
}
}
}