This closes #85 - work on jaas
This commit is contained in:
commit
58cc025653
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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">
|
||||
<!-- The security manager using JAAS -->
|
||||
<bean name="ActiveMQSecurityManager" class="org.apache.activemq.integration.jboss.security.JAASSecurityManager">
|
||||
<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>
|
||||
|
||||
<!-- JAAS uses a simple LoginModule where the user credentials and roles are
|
||||
specified as options in the constructor -->
|
||||
<bean name="ExampleConfiguration" class="org.apache.activemq.jms.example.ExampleConfiguration">
|
||||
<constructor>
|
||||
<parameter>org.apache.activemq.jms.example.ExampleLoginModule</parameter>
|
||||
<parameter>
|
||||
<map class="java.util.HashMap" keyClass="java.lang.String"
|
||||
valueClass="java.lang.String">
|
||||
<entry>
|
||||
<key>user</key>
|
||||
<value>jboss</value>
|
||||
</entry>
|
||||
<entry>
|
||||
<key>pass</key>
|
||||
<value>redhat</value>
|
||||
</entry>
|
||||
<entry>
|
||||
<key>role</key>
|
||||
<value>guest</value>
|
||||
</entry>
|
||||
</map>
|
||||
</parameter>
|
||||
</constructor>
|
||||
</bean>
|
||||
|
||||
<!-- the CallbackHandler does nothing as we don't have any user interaction -->
|
||||
<bean name="ExampleCallbackHandler" class="org.apache.activemq.jms.example.ExampleCallbackHandler"
|
||||
/>
|
||||
</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>
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue