You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by bd...@apache.org on 2017/01/17 20:56:02 UTC
[2/3] shiro git commit: Initial pass at CDI support (without
requiring a shiro.ini file)
Initial pass at CDI support (without requiring a shiro.ini file)
Fixes: #24
Project: http://git-wip-us.apache.org/repos/asf/shiro/repo
Commit: http://git-wip-us.apache.org/repos/asf/shiro/commit/59b944c0
Tree: http://git-wip-us.apache.org/repos/asf/shiro/tree/59b944c0
Diff: http://git-wip-us.apache.org/repos/asf/shiro/diff/59b944c0
Branch: refs/heads/cdi-idea
Commit: 59b944c01f51adf9e9c94c4ce07469427c974ee8
Parents: 0aec373
Author: Brian Demers <bd...@apache.org>
Authored: Mon Nov 28 16:33:21 2016 -0500
Committer: Brian Demers <bd...@apache.org>
Committed: Tue Jan 17 15:46:37 2017 -0500
----------------------------------------------------------------------
samples/cdi-core/pom.xml | 110 +++++++++
.../apache/shiro/samples/cdi/CdiQuickStart.java | 107 +++++++++
.../apache/shiro/samples/cdi/RealmProducer.java | 33 +++
.../src/main/resources/META-INF/beans.xml | 1 +
samples/cdi-core/src/main/resources/logback.xml | 33 +++
samples/cdi-core/src/main/resources/shiro.ini | 58 +++++
.../shiro/samples/cdi/CdiQuickStartIT.groovy | 25 ++
samples/cdi-web/pom.xml | 134 +++++++++++
.../shiro/samples/jaxrs/SampleApplication.java | 87 +++++++
.../samples/jaxrs/resources/HelloResource.java | 37 +++
.../samples/jaxrs/resources/SecureResource.java | 75 ++++++
.../samples/jaxrs/resources/WhoAmIResource.java | 55 +++++
samples/cdi-web/src/main/resources/logback.xml | 33 +++
samples/cdi-web/src/main/resources/shiro.ini | 43 ++++
.../cdi-web/src/main/webapp/WEB-INF/beans.xml | 1 +
samples/cdi-web/src/main/webapp/WEB-INF/web.xml | 10 +
.../web/jaxrs/ContainerIntegrationIT.groovy | 134 +++++++++++
samples/pom.xml | 2 +
support/cdi/cdi-base/pom.xml | 108 +++++++++
.../org/apache/shiro/cdi/CdiEnvironment.java | 36 +++
.../EventListenerRegistrationInterceptor.java | 74 ++++++
.../shiro/cdi/ShiroAnnotationInterceptor.java | 75 ++++++
.../org/apache/shiro/cdi/ShiroCdiExtension.java | 191 ++++++++++++++++
.../java/org/apache/shiro/cdi/Standard.java | 17 ++
.../AbstractSecurityManagerProducer.java | 134 +++++++++++
.../AuthenticationStrategyProducer.java | 15 ++
.../shiro/cdi/producers/EventBusProducer.java | 16 ++
.../cdi/producers/SessionFactoryProducer.java | 15 ++
.../SessionStorageEvaluatorProducer.java | 14 ++
.../shiro/cdi/producers/SubjectDaoProducer.java | 16 ++
.../shiro/cdi/producers/SubjectProducer.java | 21 ++
.../src/main/resources/META-INF/beans.xml | 7 +
.../javax.enterprise.inject.spi.Extension | 1 +
.../org/apache/shiro/cdi/CdiHackingTest.groovy | 112 +++++++++
.../shiro/cdi/EventBusSubscribeTest.groovy | 55 +++++
.../cdi/ShiroAnnotationInterceptorsTest.groovy | 228 +++++++++++++++++++
.../apache/shiro/cdi/AnnotationTestStub.java | 56 +++++
.../org/apache/shiro/cdi/EventBusAwareStub.java | 41 ++++
.../org/apache/shiro/cdi/EventListenerStub.java | 38 ++++
.../org/apache/shiro/cdi/StubConfiguration.java | 40 ++++
.../src/test/resources/META-INF/beans.xml | 1 +
support/cdi/cdi-core/pom.xml | 109 +++++++++
.../core/producers/SecurityManagerProducer.java | 82 +++++++
.../src/main/resources/META-INF/beans.xml | 1 +
.../org/apache/shiro/cdi/CdiHackingTest.groovy | 108 +++++++++
.../org/apache/shiro/cdi/StubConfiguration.java | 29 +++
.../src/test/resources/META-INF/beans.xml | 1 +
support/cdi/cdi-web/pom.xml | 133 +++++++++++
.../apache/shiro/cdi/web/CdiWebEnvironment.java | 43 ++++
.../apache/shiro/cdi/web/NativeSessions.java | 17 ++
.../shiro/cdi/web/ServletContainerSessions.java | 17 ++
.../main/java/org/apache/shiro/cdi/web/Web.java | 14 ++
.../producers/WebSecurityManagerProducer.java | 82 +++++++
.../producers/WebSessionManagerProvider.java | 25 ++
.../src/main/resources/META-INF/beans.xml | 1 +
.../apache/shiro/cdi/web/MoreHackingTest.groovy | 82 +++++++
.../apache/shiro/cdi/web/StubConfiguration.java | 18 ++
.../src/test/resources/META-INF/beans.xml | 1 +
support/cdi/pom.xml | 46 ++++
support/pom.xml | 1 +
60 files changed, 3099 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-core/pom.xml
----------------------------------------------------------------------
diff --git a/samples/cdi-core/pom.xml b/samples/cdi-core/pom.xml
new file mode 100644
index 0000000..b14f9db
--- /dev/null
+++ b/samples/cdi-core/pom.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<!--suppress osmorcNonOsgiMavenDependency -->
+<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">
+
+ <parent>
+ <groupId>org.apache.shiro.samples</groupId>
+ <artifactId>shiro-samples</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>samples-cdi-core</artifactId>
+ <name>Apache Shiro :: Samples :: CDI Core</name>
+ <packaging>jar</packaging>
+
+ <properties>
+ <jdk.version>1.7</jdk.version>
+ <deltaspike.version>1.7.2</deltaspike.version>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <classpathScope>test</classpathScope>
+ <mainClass>Quickstart</mainClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-cdi-core</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ </dependency>
+
+ <!-- configure logging -->
+ <!--<dependency>-->
+ <!--<groupId>org.slf4j</groupId>-->
+ <!--<artifactId>jcl-over-slf4j</artifactId>-->
+ <!--<scope>runtime</scope>-->
+ <!--</dependency>-->
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.deltaspike.modules</groupId>
+ <artifactId>deltaspike-test-control-module-api</artifactId>
+ <version>${deltaspike.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.deltaspike.modules</groupId>
+ <artifactId>deltaspike-test-control-module-impl</artifactId>
+ <version>${deltaspike.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.deltaspike.cdictrl</groupId>
+ <artifactId>deltaspike-cdictrl-weld</artifactId>
+ <version>${deltaspike.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.weld.se</groupId>
+ <artifactId>weld-se-core</artifactId>
+ <version>2.4.1.Final</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-core/src/main/java/org/apache/shiro/samples/cdi/CdiQuickStart.java
----------------------------------------------------------------------
diff --git a/samples/cdi-core/src/main/java/org/apache/shiro/samples/cdi/CdiQuickStart.java b/samples/cdi-core/src/main/java/org/apache/shiro/samples/cdi/CdiQuickStart.java
new file mode 100644
index 0000000..dbfa568
--- /dev/null
+++ b/samples/cdi-core/src/main/java/org/apache/shiro/samples/cdi/CdiQuickStart.java
@@ -0,0 +1,107 @@
+package org.apache.shiro.samples.cdi;
+
+
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.IncorrectCredentialsException;
+import org.apache.shiro.authc.LockedAccountException;
+import org.apache.shiro.authc.UnknownAccountException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.config.Ini;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.text.IniRealm;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.Initializable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.Typed;
+import javax.inject.Inject;
+
+import static com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type.Real;
+import static javafx.scene.input.KeyCode.R;
+
+@ApplicationScoped
+public class CdiQuickStart {
+
+ private static final transient Logger log = LoggerFactory.getLogger(CdiQuickStart.class);
+
+ @Inject
+ private SecurityManager securityManager;
+
+ public void runMe() {
+ // get the currently executing user:
+ Subject currentUser = new Subject.Builder(securityManager).buildSubject();
+
+ // Typically you would want to get access to the current threads's subject like this:
+ // Subject currentUser = SecurityUtils.getSubject();
+ // But that requires you to set the current Thread's SecurityManager (or a static instance)
+ // ThreadContext.bind() or SecurityUtils.setSecurityManager()
+ // For this example, we can just create a Subject directly
+
+ // Do some stuff with a Session (no need for a web or EJB container!!!)
+ Session session = currentUser.getSession();
+ session.setAttribute("someKey", "aValue");
+ String value = (String) session.getAttribute("someKey");
+ if (value.equals("aValue")) {
+ log.info("Retrieved the correct value! [" + value + "]");
+ }
+
+ // let's login the current user so we can check against roles and permissions:
+ if (!currentUser.isAuthenticated()) {
+ UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
+ token.setRememberMe(true);
+ try {
+ currentUser.login(token);
+ } catch (UnknownAccountException uae) {
+ log.info("There is no user with username of " + token.getPrincipal());
+ } catch (IncorrectCredentialsException ice) {
+ log.info("Password for account " + token.getPrincipal() + " was incorrect!");
+ } catch (LockedAccountException lae) {
+ log.info("The account for username " + token.getPrincipal() + " is locked. " +
+ "Please contact your administrator to unlock it.");
+ }
+ // ... catch more exceptions here (maybe custom ones specific to your application?
+ catch (AuthenticationException ae) {
+ //unexpected condition? error?
+ throw new ConfigurationException("Something is nog configured correctly", ae);
+ }
+ }
+
+ //say who they are:
+ //print their identifying principal (in this case, a username):
+ log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
+
+ //test a role:
+ if (currentUser.hasRole("schwartz")) {
+ log.info("May the Schwartz be with you!");
+ } else {
+ log.info("Hello, mere mortal.");
+ }
+
+ //test a typed permission (not instance-level)
+ if (currentUser.isPermitted("lightsaber:weild")) {
+ log.info("You may use a lightsaber ring. Use it wisely.");
+ } else {
+ log.info("Sorry, lightsaber rings are for schwartz masters only.");
+ }
+
+ //a (very powerful) Instance Level permission:
+ if (currentUser.isPermitted("winnebago:drive:eagle5")) {
+ log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'. " +
+ "Here are the keys - have fun!");
+ } else {
+ log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
+ }
+
+ //all done - log out!
+ currentUser.logout();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-core/src/main/java/org/apache/shiro/samples/cdi/RealmProducer.java
----------------------------------------------------------------------
diff --git a/samples/cdi-core/src/main/java/org/apache/shiro/samples/cdi/RealmProducer.java b/samples/cdi-core/src/main/java/org/apache/shiro/samples/cdi/RealmProducer.java
new file mode 100644
index 0000000..91bfd90
--- /dev/null
+++ b/samples/cdi-core/src/main/java/org/apache/shiro/samples/cdi/RealmProducer.java
@@ -0,0 +1,33 @@
+package org.apache.shiro.samples.cdi;
+
+
+import org.apache.shiro.config.Ini;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.text.IniRealm;
+import org.apache.shiro.util.Initializable;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.Typed;
+
+/**
+ *
+ */
+public class RealmProducer {
+
+ @Produces
+ @Typed({Realm.class, Initializable.class})
+ private IniRealm createIniRealm(@New IniRealm iniRealm) {
+ Ini ini = Ini.fromResourcePath("classpath:shiro.ini");
+ iniRealm.setIni(ini);
+ return iniRealm;
+ }
+
+// @Produces
+// @ApplicationScoped
+// private Ini loadShiroIni() {
+// return Ini.fromResourcePath("classpath:shiro.ini");
+// }
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-core/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/samples/cdi-core/src/main/resources/META-INF/beans.xml b/samples/cdi-core/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..330c7f6
--- /dev/null
+++ b/samples/cdi-core/src/main/resources/META-INF/beans.xml
@@ -0,0 +1 @@
+<beans/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-core/src/main/resources/logback.xml
----------------------------------------------------------------------
diff --git a/samples/cdi-core/src/main/resources/logback.xml b/samples/cdi-core/src/main/resources/logback.xml
new file mode 100644
index 0000000..25c7077
--- /dev/null
+++ b/samples/cdi-core/src/main/resources/logback.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="INFO">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+ <logger name="org.apache.shiro.samples" level="DEBUG"/>
+</configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-core/src/main/resources/shiro.ini
----------------------------------------------------------------------
diff --git a/samples/cdi-core/src/main/resources/shiro.ini b/samples/cdi-core/src/main/resources/shiro.ini
new file mode 100644
index 0000000..adca38c
--- /dev/null
+++ b/samples/cdi-core/src/main/resources/shiro.ini
@@ -0,0 +1,58 @@
+#
+# 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.
+#
+# =============================================================================
+# Quickstart INI Realm configuration
+#
+# For those that might not understand the references in this file, the
+# definitions are all based on the classic Mel Brooks' film "Spaceballs". ;)
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# Users and their assigned roles
+#
+# Each line conforms to the format defined in the
+# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc
+# -----------------------------------------------------------------------------
+[users]
+# user 'root' with password 'secret' and the 'admin' role
+root = secret, admin
+# user 'guest' with the password 'guest' and the 'guest' role
+guest = guest, guest
+# user 'presidentskroob' with password '12345' ("That's the same combination on
+# my luggage!!!" ;)), and role 'president'
+presidentskroob = 12345, president
+# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
+darkhelmet = ludicrousspeed, darklord, schwartz
+# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
+lonestarr = vespa, goodguy, schwartz
+
+# -----------------------------------------------------------------------------
+# Roles with assigned permissions
+#
+# Each line conforms to the format defined in the
+# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
+# -----------------------------------------------------------------------------
+[roles]
+# 'admin' role has all permissions, indicated by the wildcard '*'
+admin = *
+# The 'schwartz' role can do anything (*) with any lightsaber:
+schwartz = lightsaber:*
+# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
+# license plate 'eagle5' (instance specific id)
+goodguy = winnebago:drive:eagle5
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-core/src/test/groovy/org/apache/shiro/samples/cdi/CdiQuickStartIT.groovy
----------------------------------------------------------------------
diff --git a/samples/cdi-core/src/test/groovy/org/apache/shiro/samples/cdi/CdiQuickStartIT.groovy b/samples/cdi-core/src/test/groovy/org/apache/shiro/samples/cdi/CdiQuickStartIT.groovy
new file mode 100644
index 0000000..11dadb5
--- /dev/null
+++ b/samples/cdi-core/src/test/groovy/org/apache/shiro/samples/cdi/CdiQuickStartIT.groovy
@@ -0,0 +1,25 @@
+package org.apache.shiro.samples.cdi
+
+import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import javax.inject.Inject
+
+/**
+ * Simple Test for {@link CdiQuickStart}.
+ */
+@RunWith(CdiTestRunner)
+class CdiQuickStartIT {
+
+ @Inject
+ CdiQuickStart cdiQuickStart;
+
+ @Test
+ void runQuickStart() {
+
+ println("WTF")
+
+ cdiQuickStart.runMe()
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/pom.xml
----------------------------------------------------------------------
diff --git a/samples/cdi-web/pom.xml b/samples/cdi-web/pom.xml
new file mode 100644
index 0000000..050ecac
--- /dev/null
+++ b/samples/cdi-web/pom.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<!--suppress osmorcNonOsgiMavenDependency -->
+<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">
+
+ <parent>
+ <groupId>org.apache.shiro.samples</groupId>
+ <artifactId>shiro-samples</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>samples-cdi-web</artifactId>
+ <name>Apache Shiro :: Samples :: CDI Web</name>
+ <packaging>war</packaging>
+
+ <properties>
+
+ <maven.compiler.target>1.7</maven.compiler.target>
+ <maven.compiler.source>1.7</maven.compiler.source>
+
+ <tomee.version>7.0.2</tomee.version>
+ <tomee.classifier>plus</tomee.classifier>
+
+ <jdk.version>1.7</jdk.version>
+ <deltaspike.version>1.7.2</deltaspike.version>
+
+ <jersey.version>2.23.2</jersey.version>
+ <mainClass>org.apache.shiro.samples.jaxrs.SampleApplication</mainClass>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <configuration>
+ <mainClass>org.apache.shiro.samples.jaxrs.SampleApplication</mainClass>
+ <classpathScope>test</classpathScope>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.tomee.maven</groupId>
+ <artifactId>tomee-maven-plugin</artifactId>
+ <version>${tomee.version}</version>
+ <configuration>
+ <tomeeVersion>${tomee.version}</tomeeVersion>
+ <tomeeClassifier>${tomee.classifier}</tomeeClassifier>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-servlet-plugin</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-cdi-web</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-jaxrs</artifactId>
+ </dependency>
+
+ <dependency>
+ <!-- Required for any libraries that expect to call the commons logging APIs -->
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+
+
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <version>2.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>javax.annotation-api</artifactId>
+ <version>1.3</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ <version>1.2</version>
+ <scope>provided</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.apache.openwebbeans</groupId>
+ <artifactId>openwebbeans-impl</artifactId>
+ <version>1.7.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/SampleApplication.java
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/SampleApplication.java b/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/SampleApplication.java
new file mode 100644
index 0000000..a13c885
--- /dev/null
+++ b/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/SampleApplication.java
@@ -0,0 +1,87 @@
+/*
+ * 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.shiro.samples.jaxrs;
+
+import org.apache.shiro.samples.jaxrs.resources.HelloResource;
+import org.apache.shiro.samples.jaxrs.resources.SecureResource;
+import org.apache.shiro.samples.jaxrs.resources.WhoAmIResource;
+import org.apache.shiro.web.jaxrs.ShiroFeature;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Simple JAX-RS {@link Application} that is implementation agnostic.
+ * @since 1.4
+ */
+@ApplicationPath("/")
+public class SampleApplication extends Application {
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> classes = new HashSet<Class<?>>();
+
+ // register Shiro
+ classes.add(ShiroFeature.class);
+
+ // register resources
+ classes.add(HelloResource.class);
+ classes.add(SecureResource.class);
+ classes.add(WhoAmIResource.class);
+
+ return classes;
+ }
+
+
+// private static final URI BASE_URI = URI.create("http://localhost:8080/");
+//
+// public static void main(String[] args) {
+// try {
+// System.out.println("Jersey CDI Example App");
+//
+// final Weld weld = new Weld();
+// weld.initialize();
+//
+// final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, createJaxRsApp(), false);
+// Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+// @Override
+// public void run() {
+// server.shutdownNow();
+// weld.shutdown();
+// }
+// }));
+// server.start();
+//
+// System.out.println(String.format("Application started.\nTry out %s%s\nStop the application using CTRL+C",
+// BASE_URI, "application.wadl"));
+//
+// Thread.currentThread().join();
+// } catch (IOException | InterruptedException ex) {
+// LoggerFactory.getLogger(SampleApplication.class).error(null, ex);
+// }
+//
+// }
+//
+// private static ResourceConfig createJaxRsApp() {
+// return ResourceConfig.forApplicationClass(SampleApplication.class);
+// }
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/HelloResource.java
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/HelloResource.java b/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/HelloResource.java
new file mode 100644
index 0000000..400f503
--- /dev/null
+++ b/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/HelloResource.java
@@ -0,0 +1,37 @@
+/*
+ * 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.shiro.samples.jaxrs.resources;
+
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+
+@Path("say")
+public class HelloResource {
+
+
+ @Produces({"application/json","plain/text"})
+ @GET
+ public String saySomething(@QueryParam("words") @DefaultValue("Hello!") String words) {
+ return words;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/SecureResource.java
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/SecureResource.java b/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/SecureResource.java
new file mode 100644
index 0000000..c590987
--- /dev/null
+++ b/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/SecureResource.java
@@ -0,0 +1,75 @@
+/*
+ * 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.shiro.samples.jaxrs.resources;
+
+
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.authz.annotation.RequiresGuest;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.apache.shiro.authz.annotation.RequiresUser;
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+
+@Path("secure")
+@Produces({"application/json","plain/text"})
+public class SecureResource {
+
+
+ @RequiresPermissions("lightsaber:requiresPermissions")
+ @Path("RequiresPermissions")
+ @GET
+ public String protectedByRequiresPermissions() {
+ return "protected";
+ }
+
+ @RequiresRoles("admin")
+ @Path("RequiresRoles")
+ @GET
+ public String protectedByRequiresRoles() {
+ return "protected";
+ }
+
+ @RequiresUser
+ @Path("RequiresUser")
+ @GET
+ public String protectedByRequiresUser() {
+ return "protected";
+ }
+
+ @RequiresGuest
+ @Path("RequiresGuest")
+ @GET
+ public String protectedByRequiresGuest() {
+ return "not protected";
+ }
+
+ @RequiresAuthentication
+ @Path("RequiresAuthentication")
+ @GET
+ public String protectedByRequiresAuthentication() {
+ return "protected";
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/WhoAmIResource.java
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/WhoAmIResource.java b/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/WhoAmIResource.java
new file mode 100644
index 0000000..337e706
--- /dev/null
+++ b/samples/cdi-web/src/main/java/org/apache/shiro/samples/jaxrs/resources/WhoAmIResource.java
@@ -0,0 +1,55 @@
+/*
+ * 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.shiro.samples.jaxrs.resources;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.cdi.web.Web;
+import org.apache.shiro.subject.Subject;
+
+import javax.annotation.ManagedBean;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+@Path("whoami")
+@Produces({"application/json","plain/text"})
+//@RequestScoped
+//@ApplicationScoped
+//@ManagedBean
+public class WhoAmIResource {
+
+ @Inject
+ private Subject subject;
+
+ @GET
+ public String whoAmI() {
+
+// Subject subject = SecurityUtils.getSubject();
+
+ Object principal = subject.getPrincipal();
+
+ if (principal == null) {
+ principal = "guest";
+ }
+
+ return principal.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/main/resources/logback.xml
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/main/resources/logback.xml b/samples/cdi-web/src/main/resources/logback.xml
new file mode 100644
index 0000000..283b72d
--- /dev/null
+++ b/samples/cdi-web/src/main/resources/logback.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+ <logger name="org.apache.shiro" level="DEBUG"/>
+</configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/main/resources/shiro.ini
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/main/resources/shiro.ini b/samples/cdi-web/src/main/resources/shiro.ini
new file mode 100644
index 0000000..54fa949
--- /dev/null
+++ b/samples/cdi-web/src/main/resources/shiro.ini
@@ -0,0 +1,43 @@
+#
+# 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.
+
+[main]
+cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
+
+sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
+sessionManager.sessionIdUrlRewritingEnabled = false
+
+securityManager.sessionManager = $sessionManager
+securityManager.cacheManager = $cacheManager
+
+[urls]
+/** = authcBasic[permissive]
+
+[users]
+# format: username = password, role1, role2, ..., roleN
+root = secret,admin
+guest = guest,guest
+presidentskroob = 12345,president
+darkhelmet = ludicrousspeed,darklord,schwartz
+lonestarr = vespa,goodguy,schwartz
+
+[roles]
+# format: roleName = permission1, permission2, ..., permissionN
+admin = *
+schwartz = lightsaber:*
+goodguy = winnebago:drive:eagle5
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/main/webapp/WEB-INF/beans.xml
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/main/webapp/WEB-INF/beans.xml b/samples/cdi-web/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000..330c7f6
--- /dev/null
+++ b/samples/cdi-web/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1 @@
+<beans/>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/main/webapp/WEB-INF/web.xml b/samples/cdi-web/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..852ba1f
--- /dev/null
+++ b/samples/cdi-web/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,10 @@
+<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
+ version="3.1">
+
+ <display-name>test</display-name>
+
+
+
+</web-app>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/cdi-web/src/test/groovy/org/apache/shiro/web/jaxrs/ContainerIntegrationIT.groovy
----------------------------------------------------------------------
diff --git a/samples/cdi-web/src/test/groovy/org/apache/shiro/web/jaxrs/ContainerIntegrationIT.groovy b/samples/cdi-web/src/test/groovy/org/apache/shiro/web/jaxrs/ContainerIntegrationIT.groovy
new file mode 100644
index 0000000..4dd84cc
--- /dev/null
+++ b/samples/cdi-web/src/test/groovy/org/apache/shiro/web/jaxrs/ContainerIntegrationIT.groovy
@@ -0,0 +1,134 @@
+/*
+ * 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.shiro.web.jaxrs
+
+//import org.apache.shiro.testing.web.AbstractContainerIT
+//import org.junit.Test;
+//
+//import static com.jayway.restassured.RestAssured.*
+//import static org.hamcrest.Matchers.*
+
+public class ContainerIntegrationIT {
+// extends AbstractContainerIT {
+
+// @Test
+// void testNoAuthResource() {
+//
+// get(getBaseUri() + "say")
+// .then()
+// .assertThat()
+// .statusCode(is(200)).and()
+// .body(equalTo("Hello!"))
+// }
+//
+// @Test
+// void testSecuredRequiresAuthentication() {
+//
+// get(getBaseUri() + "secure/RequiresAuthentication")
+// .then()
+// .assertThat().statusCode(is(401))
+//
+// given()
+// .header("Authorization", getBasicAuthorizationHeaderValue("root", "secret"))
+// .when()
+// .get(getBaseUri() + "secure/RequiresAuthentication")
+// .then()
+// .assertThat()
+// .statusCode(is(200)).and()
+// .body(equalTo("protected"))
+// }
+//
+// @Test
+// void testSecuredRequiresUser() {
+//
+// get(getBaseUri() + "secure/RequiresUser")
+// .then()
+// .assertThat().statusCode(is(401))
+//
+// given()
+// .header("Authorization", getBasicAuthorizationHeaderValue("root", "secret"))
+// .when()
+// .get(getBaseUri() + "secure/RequiresUser")
+// .then()
+// .assertThat()
+// .statusCode(is(200)).and()
+// .body(equalTo("protected"))
+// }
+//
+// @Test
+// void testSecuredRequiresRoles() {
+//
+// get(getBaseUri() + "secure/RequiresRoles")
+// .then()
+// .assertThat().statusCode(is(401))
+//
+// given()
+// .header("Authorization", getBasicAuthorizationHeaderValue("guest", "guest"))
+// .when()
+// .get(getBaseUri() + "secure/RequiresRoles")
+// .then()
+// .assertThat()
+// .statusCode(is(403)).and()
+//
+// given()
+// .header("Authorization", getBasicAuthorizationHeaderValue("root", "secret"))
+// .when()
+// .get(getBaseUri() + "secure/RequiresRoles")
+// .then()
+// .assertThat()
+// .statusCode(is(200)).and()
+// .body(equalTo("protected"))
+// }
+//
+// @Test
+// void testSecuredRequiresPermissions() {
+//
+// get(getBaseUri() + "secure/RequiresPermissions")
+// .then()
+// .assertThat().statusCode(is(401))
+//
+// given()
+// .header("Authorization", getBasicAuthorizationHeaderValue("guest", "guest"))
+// .when()
+// .get(getBaseUri() + "secure/RequiresPermissions")
+// .then()
+// .assertThat()
+// .statusCode(is(403)).and()
+//
+// given()
+// .header("Authorization", getBasicAuthorizationHeaderValue("lonestarr", "vespa"))
+// .when()
+// .get(getBaseUri() + "secure/RequiresPermissions")
+// .then()
+// .assertThat()
+// .statusCode(is(200)).and()
+// .body(equalTo("protected"))
+// }
+//
+// @Test
+// void testSecuredRequiresGuest() {
+//
+// get(getBaseUri() + "secure/RequiresGuest")
+// .then()
+// .assertThat()
+// .statusCode(is(200)).and()
+// .body(equalTo("not protected"))
+// }
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/samples/pom.xml
----------------------------------------------------------------------
diff --git a/samples/pom.xml b/samples/pom.xml
index 72b9193..bb232e2 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -47,6 +47,8 @@
<module>quickstart-guice</module>
<module>servlet-plugin</module>
<module>jaxrs</module>
+ <module>cdi-core</module>
+ <module>cdi-web</module>
</modules>
<reporting>
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/pom.xml
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/pom.xml b/support/cdi/cdi-base/pom.xml
new file mode 100644
index 0000000..f21deb2
--- /dev/null
+++ b/support/cdi/cdi-base/pom.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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">
+
+ <parent>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-cdi</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>shiro-cdi-base</artifactId>
+ <name>Apache Shiro :: Support :: CDI Base</name>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ <version>1.2</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>javax.annotation-api</artifactId>
+ <version>1.3</version>
+ </dependency>
+
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.deltaspike.modules</groupId>
+ <artifactId>deltaspike-test-control-module-api</artifactId>
+ <version>${deltaspike.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.deltaspike.modules</groupId>
+ <artifactId>deltaspike-test-control-module-impl</artifactId>
+ <version>${deltaspike.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.deltaspike.cdictrl</groupId>
+ <artifactId>deltaspike-cdictrl-weld</artifactId>
+ <version>${deltaspike.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.weld.se</groupId>
+ <artifactId>weld-se-core</artifactId>
+ <version>2.4.1.Final</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.apache.shiro.cdi.base</Bundle-SymbolicName>
+ <Export-Package>org.apache.shiro.cdi*;version=${project.version}</Export-Package>
+ <Import-Package>
+ org.apache.shiro*;version="${shiro.osgi.importRange}",
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/CdiEnvironment.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/CdiEnvironment.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/CdiEnvironment.java
new file mode 100644
index 0000000..1177e2d
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/CdiEnvironment.java
@@ -0,0 +1,36 @@
+/*
+ * 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.shiro.cdi;
+
+import org.apache.shiro.env.Environment;
+import org.apache.shiro.mgt.SecurityManager;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+@ApplicationScoped
+public class CdiEnvironment implements Environment {
+
+ @Inject
+ private SecurityManager securityManager;
+
+ @Override
+ public SecurityManager getSecurityManager() {
+ return securityManager;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/EventListenerRegistrationInterceptor.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/EventListenerRegistrationInterceptor.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/EventListenerRegistrationInterceptor.java
new file mode 100644
index 0000000..ee31e5b
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/EventListenerRegistrationInterceptor.java
@@ -0,0 +1,74 @@
+/*
+ * 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.shiro.cdi;
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.EventBusAware;
+import org.apache.shiro.event.support.DefaultEventBus;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Priority;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InterceptorBinding;
+import javax.interceptor.InvocationContext;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@EventListenerRegistrationInterceptor.ProcessShiroEventBusConsumer
+@Interceptor
+@Priority(Interceptor.Priority.LIBRARY_BEFORE + 10)
+class EventListenerRegistrationInterceptor {
+
+ private final EventBus eventBus;
+
+ @Inject
+ public EventListenerRegistrationInterceptor(EventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
+ @PostConstruct
+ public Object invoke(final InvocationContext invocationContext) throws Throwable {
+
+ Object target = invocationContext.getTarget();
+
+ // If an object is EventBusAware, do NOT register events directly, just call setEventBus()
+ if(target instanceof EventBusAware) {
+ ((EventBusAware) target).setEventBus(eventBus);
+ }
+ else {
+ eventBus.register(target);
+ }
+
+ return invocationContext.proceed();
+ }
+
+ /**
+ * A marker annotation, used to assign Shiro annotations problematically.
+ */
+ @InterceptorBinding
+ @Target({ElementType.TYPE})
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface ProcessShiroEventBusConsumer {}
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/ShiroAnnotationInterceptor.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/ShiroAnnotationInterceptor.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/ShiroAnnotationInterceptor.java
new file mode 100644
index 0000000..e898be2
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/ShiroAnnotationInterceptor.java
@@ -0,0 +1,75 @@
+/*
+ * 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.shiro.cdi;
+
+import org.apache.shiro.aop.MethodInterceptor;
+import org.apache.shiro.aop.MethodInvocation;
+import org.apache.shiro.authz.aop.AnnotationsAuthorizingMethodInterceptor;
+
+import javax.annotation.Priority;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InterceptorBinding;
+import javax.interceptor.InvocationContext;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+
+@Interceptor
+@ShiroAnnotationInterceptor.ProcessShiroAnnotations
+@Priority(Interceptor.Priority.LIBRARY_BEFORE + 10)
+final class ShiroAnnotationInterceptor extends AnnotationsAuthorizingMethodInterceptor implements MethodInterceptor {
+
+ @AroundInvoke
+ public Object invoke(final InvocationContext invocationContext) throws Throwable {
+
+ return invoke(new MethodInvocation() {
+ @Override
+ public Object proceed() throws Throwable {
+ return invocationContext.proceed();
+ }
+
+ @Override
+ public Method getMethod() {
+ return invocationContext.getMethod();
+ }
+
+ @Override
+ public Object[] getArguments() {
+ return invocationContext.getParameters();
+ }
+
+ @Override
+ public Object getThis() {
+ return invocationContext.getTarget();
+ }
+ });
+ }
+
+ /**
+ * A marker annotation, used to assign Shiro annotations problematically.
+ */
+ @InterceptorBinding
+ @Target({ElementType.TYPE})
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface ProcessShiroAnnotations {}
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/ShiroCdiExtension.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/ShiroCdiExtension.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/ShiroCdiExtension.java
new file mode 100644
index 0000000..de6a7d9
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/ShiroCdiExtension.java
@@ -0,0 +1,191 @@
+/*
+ * 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.shiro.cdi;
+
+import org.apache.shiro.cdi.EventListenerRegistrationInterceptor.ProcessShiroEventBusConsumer;
+import org.apache.shiro.cdi.ShiroAnnotationInterceptor.ProcessShiroAnnotations;
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.authz.annotation.RequiresGuest;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.apache.shiro.authz.annotation.RequiresUser;
+import org.apache.shiro.event.EventBusAware;
+import org.apache.shiro.event.Subscribe;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.inject.spi.ProcessBean;
+import javax.enterprise.inject.spi.WithAnnotations;
+import javax.enterprise.util.AnnotationLiteral;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ShiroCdiExtension implements Extension {
+
+ private List<Bean<?>> eagerBeansList = new ArrayList<Bean<?>>();
+
+ // Registering instances with Shiro's EventBus is a 4 part process:
+ // 1. registerEventListeners()/registerEventBusAware() detects any AnnotatedType with an 'Subscribe' annotation
+ // and adds an additional annotation 'ProcessShiroEventBusConsumer' to mark the bean for interception
+ // 2. collectEventListeners() finds the Beans that were Annotated with 'ProcessShiroEventBusConsumer' and adds
+ // them to the 'eagerBeansList'
+ // 3. eagerLoadBeans() initializes these beans
+ // 4. EventListenerRegistrationInterceptor adds a 'PostConstruct' interceptor that registers the instance with the
+ // EventBus instance or calls setEventBus()
+
+ private <X> void registerEventBusAware(@Observes ProcessAnnotatedType<X> pat) {
+
+ if(EventBusAware.class.isAssignableFrom(pat.getAnnotatedType().getJavaClass())) {
+ addProcessShiroEventConsumerAnnotation(pat);
+ }
+ }
+
+ private <X> void registerEventListeners(@Observes @WithAnnotations({Subscribe.class}) ProcessAnnotatedType<X> pat) {
+ addProcessShiroEventConsumerAnnotation(pat);
+ }
+
+ private <X> void addProcessShiroEventConsumerAnnotation(ProcessAnnotatedType<X> pat) {
+
+ // wrap this to override the annotations of the class
+ final AnnotatedType<X> at = pat.getAnnotatedType();
+
+ pat.setAnnotatedType(new AdditionalAnntoationType<X, ProcessShiroEventBusConsumer>(at, ProcessShiroEventBusConsumer.class) {
+ @Override
+ public Set<Annotation> getAnnotations() {
+ Set<Annotation> original = at.getAnnotations();
+ Set<Annotation> annotations = new HashSet<>(original);
+ annotations.add(new AnnotationLiteral<ProcessShiroEventBusConsumer>() {});
+ return annotations;
+ }
+ });
+ }
+
+ private <T> void collectEventListeners(@Observes ProcessBean<T> event) {
+ if(event.getAnnotated().isAnnotationPresent(ApplicationScoped.class)) {
+ if(event.getAnnotated().isAnnotationPresent(ProcessShiroEventBusConsumer.class)
+ || EventBusAware.class.isAssignableFrom(event.getBean().getBeanClass()) ) {
+ eagerBeansList.add(event.getBean());
+ }
+ }
+ }
+
+ private void eagerLoadBeans(@Observes AfterDeploymentValidation event, BeanManager beanManager) {
+ for (Bean<?> bean : eagerBeansList) {
+ // note: toString() is important to instantiate the bean
+ beanManager.getReference(bean, bean.getBeanClass(), beanManager.createCreationalContext(bean)).toString();
+ }
+ }
+
+ /**
+ * Adds the {@link ProcessShiroAnnotations} annotation to any Bean containing one of the following annotations
+ * {@link RequiresAuthentication}, {@link RequiresGuest}, {@link RequiresUser}, {@link RequiresRoles},
+ * or {@link RequiresPermissions}. This allows the {@link ShiroAnnotationInterceptor} to process the
+ * Shiro annotations.
+ */
+ private <X> void registerAuthAnnotations(@Observes @WithAnnotations({
+ RequiresAuthentication.class,
+ RequiresGuest.class,
+ RequiresUser.class,
+ RequiresRoles.class,
+ RequiresPermissions.class})
+ ProcessAnnotatedType<X> pat) {
+
+ // wrap this to override the annotations of the class
+ final AnnotatedType<X> at = pat.getAnnotatedType();
+
+ pat.setAnnotatedType(new AdditionalAnntoationType<X, ProcessShiroAnnotations>(at, ProcessShiroAnnotations.class) {
+ @Override
+ public Set<Annotation> getAnnotations() {
+ Set<Annotation> original = at.getAnnotations();
+ Set<Annotation> annotations = new HashSet<>(original);
+
+ annotations.add(new AnnotationLiteral<ProcessShiroAnnotations>() {});
+
+ return annotations;
+ }
+ });
+ }
+
+ private abstract static class AdditionalAnntoationType<T, X extends Annotation> implements AnnotatedType<T> {
+
+ private final AnnotatedType<T> delegate;
+ private final Class<X> extraAnnotation;
+
+ private AdditionalAnntoationType(AnnotatedType<T> delegate, Class<X> extraAnnotation) {
+ this.delegate = delegate;
+ this.extraAnnotation = extraAnnotation;
+ }
+
+ @Override
+ public Set<AnnotatedConstructor<T>> getConstructors() {
+ return delegate.getConstructors();
+ }
+
+ @Override
+ public Set<AnnotatedField<? super T>> getFields() {
+ return delegate.getFields();
+ }
+
+ @Override
+ public Class<T> getJavaClass() {
+ return delegate.getJavaClass();
+ }
+
+ @Override
+ public Set<AnnotatedMethod<? super T>> getMethods() {
+ return delegate.getMethods();
+ }
+
+ @Override
+ public <T extends Annotation> T getAnnotation(final Class<T> annType) {
+ return delegate.getAnnotation(annType);
+ }
+
+ @Override
+ public Type getBaseType() {
+ return delegate.getBaseType();
+ }
+
+ @Override
+ public Set<Type> getTypeClosure() {
+ return delegate.getTypeClosure();
+ }
+
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annType) {
+ return extraAnnotation.equals(annType)
+ || delegate.isAnnotationPresent(annType);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/Standard.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/Standard.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/Standard.java
new file mode 100644
index 0000000..6daff2e
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/Standard.java
@@ -0,0 +1,17 @@
+package org.apache.shiro.cdi;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Qualifier
+@Retention(RUNTIME)
+@Target({TYPE, METHOD, FIELD, PARAMETER})
+public @interface Standard {
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/AbstractSecurityManagerProducer.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/AbstractSecurityManagerProducer.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/AbstractSecurityManagerProducer.java
new file mode 100644
index 0000000..80f1f10
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/AbstractSecurityManagerProducer.java
@@ -0,0 +1,134 @@
+/*
+ * 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.shiro.cdi.producers;
+
+import org.apache.shiro.authc.pam.AuthenticationStrategy;
+import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
+import org.apache.shiro.authz.ModularRealmAuthorizer;
+import org.apache.shiro.authz.permission.PermissionResolver;
+import org.apache.shiro.authz.permission.RolePermissionResolver;
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.mgt.RememberMeManager;
+import org.apache.shiro.mgt.SubjectDAO;
+import org.apache.shiro.mgt.SubjectFactory;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.util.Destroyable;
+import org.apache.shiro.util.Initializable;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class AbstractSecurityManagerProducer {
+
+ @Inject
+ private Instance<Initializable> initializables;
+
+ @Inject
+ private Instance<Destroyable> destroyables;
+
+ @Inject
+ private Instance<Object> objectInstances;
+
+
+
+
+ protected abstract DefaultSecurityManager securityManager(DefaultSecurityManager securityManager,
+ Instance<Realm> realms,
+ EventBus eventBus,
+ SessionManager sessionManager,
+ Instance<CacheManager> cacheManager,
+ SubjectDAO subjectDAO,
+ SubjectFactory subjectFactory,
+ Instance<RememberMeManager> rememberMeManager,
+ AuthenticationStrategy authenticationStrategy,
+ Instance<PermissionResolver> permissionResolver,
+ Instance<RolePermissionResolver> rolePermissionResolver);
+
+
+ protected <T extends DefaultSecurityManager> T configureSecurityManager(T securityManager,
+ Instance<Realm> realms,
+ EventBus eventBus,
+ SessionManager sessionManager,
+ Instance<CacheManager> cacheManager,
+ SubjectDAO subjectDAO,
+ SubjectFactory subjectFactory,
+ Instance<RememberMeManager> rememberMeManager,
+ AuthenticationStrategy authenticationStrategy,
+ Instance<PermissionResolver> permissionResolver,
+ Instance<RolePermissionResolver> rolePermissionResolver) {
+ securityManager.setEventBus(eventBus);
+
+ // Set the cache manager if available
+ if(!cacheManager.isUnsatisfied()) {
+ securityManager.setCacheManager(cacheManager.get());
+ }
+
+ if(!rememberMeManager.isUnsatisfied()) {
+ securityManager.setRememberMeManager(rememberMeManager.get());
+ }
+
+ ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
+ authenticator.setAuthenticationStrategy(authenticationStrategy);
+ ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
+
+ if (permissionResolver != null && !permissionResolver.isUnsatisfied()) {
+ authorizer.setPermissionResolver(permissionResolver.get());
+ }
+
+ if (rolePermissionResolver != null && !rolePermissionResolver.isUnsatisfied()) {
+ authorizer.setRolePermissionResolver(rolePermissionResolver.get());
+ }
+
+ securityManager.setAuthenticator(authenticator);
+ securityManager.setAuthorizer(authorizer);
+ securityManager.setSessionManager(sessionManager);
+ securityManager.setSubjectDAO(subjectDAO);
+ securityManager.setSubjectFactory(subjectFactory);
+
+ List<Realm> realmList = new ArrayList<>();
+ for (Realm realm : realms) {
+ realmList.add(realm);
+ }
+ securityManager.setRealms(realmList);
+
+ return securityManager;
+ }
+
+
+// @PostConstruct
+// void init() {
+// for(Initializable initializable : initializables) {
+// initializable.init();
+// }
+// }
+
+// @PreDestroy
+// void destroy() throws Exception {
+// for(Destroyable destroyable : destroyables) {
+// destroyable.destroy();
+// }
+// }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/AuthenticationStrategyProducer.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/AuthenticationStrategyProducer.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/AuthenticationStrategyProducer.java
new file mode 100644
index 0000000..ef1c976
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/AuthenticationStrategyProducer.java
@@ -0,0 +1,15 @@
+package org.apache.shiro.cdi.producers;
+
+import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
+
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.Produces;
+
+public class AuthenticationStrategyProducer {
+
+ @Produces
+ protected AtLeastOneSuccessfulStrategy authenticationStrategy(@New AtLeastOneSuccessfulStrategy authenticationStrategy) {
+ return authenticationStrategy;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/EventBusProducer.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/EventBusProducer.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/EventBusProducer.java
new file mode 100644
index 0000000..4c56d89
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/EventBusProducer.java
@@ -0,0 +1,16 @@
+package org.apache.shiro.cdi.producers;
+
+import org.apache.shiro.event.support.DefaultEventBus;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.Produces;
+
+public class EventBusProducer {
+
+ @Produces
+ @ApplicationScoped
+ DefaultEventBus eventBusWTF(@New DefaultEventBus eventBus) {
+ return eventBus;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SessionFactoryProducer.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SessionFactoryProducer.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SessionFactoryProducer.java
new file mode 100644
index 0000000..f0984c3
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SessionFactoryProducer.java
@@ -0,0 +1,15 @@
+package org.apache.shiro.cdi.producers;
+
+import org.apache.shiro.session.mgt.SessionFactory;
+import org.apache.shiro.session.mgt.SimpleSessionFactory;
+
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.Produces;
+
+public class SessionFactoryProducer {
+
+ @Produces
+ protected SessionFactory sessionFactory(@New SimpleSessionFactory sessionFactory) {
+ return sessionFactory;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SessionStorageEvaluatorProducer.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SessionStorageEvaluatorProducer.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SessionStorageEvaluatorProducer.java
new file mode 100644
index 0000000..473a11e
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SessionStorageEvaluatorProducer.java
@@ -0,0 +1,14 @@
+package org.apache.shiro.cdi.producers;
+
+import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
+
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.Produces;
+
+public class SessionStorageEvaluatorProducer {
+
+ @Produces
+ DefaultSessionStorageEvaluator sessionStorageEvaluator(@New DefaultSessionStorageEvaluator sessionStorageEvaluator) {
+ return sessionStorageEvaluator;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SubjectDaoProducer.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SubjectDaoProducer.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SubjectDaoProducer.java
new file mode 100644
index 0000000..aa3a6d5
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SubjectDaoProducer.java
@@ -0,0 +1,16 @@
+package org.apache.shiro.cdi.producers;
+
+import org.apache.shiro.mgt.DefaultSubjectDAO;
+import org.apache.shiro.mgt.SessionStorageEvaluator;
+
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.Produces;
+
+public class SubjectDaoProducer {
+
+ @Produces
+ DefaultSubjectDAO subjectDAO(@New DefaultSubjectDAO subjectDAO, SessionStorageEvaluator sessionStorageEvaluator) {
+ subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator);
+ return subjectDAO;
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SubjectProducer.java
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SubjectProducer.java b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SubjectProducer.java
new file mode 100644
index 0000000..cd28db6
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/java/org/apache/shiro/cdi/producers/SubjectProducer.java
@@ -0,0 +1,21 @@
+package org.apache.shiro.cdi.producers;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.ThreadContext;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Produces;
+
+public class SubjectProducer {
+
+ @Produces
+ @RequestScoped
+ protected Subject subject(SecurityManager securityManager) {
+ if (ThreadContext.getSecurityManager() == null) {
+ ThreadContext.bind(securityManager);
+ }
+ return SecurityUtils.getSubject();
+ }
+}
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/resources/META-INF/beans.xml b/support/cdi/cdi-base/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..632b301
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,7 @@
+<beans>
+ <!--xmlns="http://xmlns.jcp.org/xml/ns/javaee"-->
+ <!--xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"-->
+ <!--xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee-->
+ <!--http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"-->
+ <!--bean-discovery-mode="all">-->
+</beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/support/cdi/cdi-base/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..1e6701c
--- /dev/null
+++ b/support/cdi/cdi-base/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1 @@
+org.apache.shiro.cdi.ShiroCdiExtension
http://git-wip-us.apache.org/repos/asf/shiro/blob/59b944c0/support/cdi/cdi-base/src/test/groovy/org/apache/shiro/cdi/CdiHackingTest.groovy
----------------------------------------------------------------------
diff --git a/support/cdi/cdi-base/src/test/groovy/org/apache/shiro/cdi/CdiHackingTest.groovy b/support/cdi/cdi-base/src/test/groovy/org/apache/shiro/cdi/CdiHackingTest.groovy
new file mode 100644
index 0000000..4d687cc
--- /dev/null
+++ b/support/cdi/cdi-base/src/test/groovy/org/apache/shiro/cdi/CdiHackingTest.groovy
@@ -0,0 +1,112 @@
+/*
+ * 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.shiro.cdi
+
+import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner
+import org.apache.shiro.authc.Authenticator
+import org.apache.shiro.authz.Authorizer
+import org.apache.shiro.authz.permission.PermissionResolver
+import org.apache.shiro.cache.CacheManager
+import org.apache.shiro.event.EventBus
+import org.apache.shiro.mgt.DefaultSecurityManager
+import org.apache.shiro.mgt.RememberMeManager
+import org.apache.shiro.mgt.SecurityManager
+import org.apache.shiro.mgt.SubjectDAO
+import org.apache.shiro.mgt.SubjectFactory
+import org.apache.shiro.realm.Realm
+import org.apache.shiro.session.mgt.DefaultSessionKey
+import org.apache.shiro.session.mgt.SessionManager
+import org.apache.shiro.subject.Subject
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import javax.enterprise.context.ApplicationScoped
+import javax.enterprise.inject.Default
+import javax.enterprise.inject.Instance
+import javax.inject.Inject
+
+import static org.hamcrest.Matchers.*
+
+import static org.junit.Assert.*
+
+/**
+ * Hacking around with CDI and Shiro.
+ */
+@RunWith(CdiTestRunner.class)
+@Default
+@ApplicationScoped
+public class CdiHackingTest {
+
+// @Inject
+// private SecurityManager securityManager;
+//
+// @Inject
+// private CdiEnvironment cdiEnvironment;
+//
+// @Inject
+// private EventBus eventBus;
+//
+// @Inject
+// private Instance<Realm> realms;
+//
+// @Inject
+// private SessionManager sessionManager
+//
+// @Inject
+// private Instance<CacheManager> cacheManager;
+//
+// @Inject
+// private SubjectDAO subjectDAO;
+//
+// @Inject
+// private SubjectFactory subjectFactory;
+//
+// @Inject
+// private Instance<RememberMeManager> rememberMeManager;
+//
+// @Inject
+// private Instance<PermissionResolver> permissionResolver;
+//
+// @Inject
+// private Subject subject;
+
+ @Test
+ public void doSomeStuff() {
+
+// assertNotNull(eventBus)
+// assertNotNull(subjectFactory)
+// assertNotNull(subjectDAO)
+// assertNotNull(sessionManager)
+//
+// assertTrue(rememberMeManager.isUnsatisfied())
+// assertTrue(cacheManager.isUnsatisfied())
+//
+// assertNotNull(permissionResolver.get())
+//
+// assertSame cdiEnvironment.securityManager, securityManager
+// assertThat securityManager, instanceOf(DefaultSecurityManager)
+//
+// assertEquals sessionManager, securityManager.getSessionManager()
+//// sessionManager.getSession(new DefaultSessionKey("foo"))
+//
+// assertFalse subject.isAuthenticated()
+
+
+ }
+}