diff --git a/jaspic/invoke-ejb-cdi/pom.xml b/jaspic/invoke-ejb-cdi/pom.xml new file mode 100644 index 000000000..c69615336 --- /dev/null +++ b/jaspic/invoke-ejb-cdi/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + + org.javaee7 + jaspic + 1.0-SNAPSHOT + ../pom.xml + + + jaspic-invoke-ejb-cdi + + war + + Java EE 7 Sample: jaspic - invoke EJB and CDI + + + + org.javaee7 + jaspic-common + 1.0-SNAPSHOT + + + diff --git a/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/bean/CDIBean.java b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/bean/CDIBean.java new file mode 100644 index 000000000..e2429222a --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/bean/CDIBean.java @@ -0,0 +1,14 @@ +package org.javaee7.jaspic.invoke.bean; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; + +@Named +@RequestScoped +public class CDIBean { + + public String getText() { + return "Called from CDI"; + } + +} diff --git a/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/bean/EJBBean.java b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/bean/EJBBean.java new file mode 100644 index 000000000..07df114cd --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/bean/EJBBean.java @@ -0,0 +1,12 @@ +package org.javaee7.jaspic.invoke.bean; + +import javax.ejb.Stateless; + +@Stateless +public class EJBBean { + + public String getText() { + return "Called from EJB"; + } + +} diff --git a/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/sam/SamAutoRegistrationListener.java b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/sam/SamAutoRegistrationListener.java new file mode 100644 index 000000000..dc6b780ca --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/sam/SamAutoRegistrationListener.java @@ -0,0 +1,22 @@ +package org.javaee7.jaspic.invoke.sam; + +import javax.servlet.ServletContextEvent; +import javax.servlet.annotation.WebListener; + +import org.javaee7.jaspic.common.BaseServletContextListener; +import org.javaee7.jaspic.common.JaspicUtils; + +/** + * + * @author Arjan Tijms + * + */ +@WebListener +public class SamAutoRegistrationListener extends BaseServletContextListener { + + @Override + public void contextInitialized(ServletContextEvent sce) { + JaspicUtils.registerSAM(sce.getServletContext(), new TestServerAuthModule()); + } + +} \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/sam/TestServerAuthModule.java b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/sam/TestServerAuthModule.java new file mode 100644 index 000000000..a8c918dfe --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/sam/TestServerAuthModule.java @@ -0,0 +1,127 @@ +package org.javaee7.jaspic.invoke.sam; + +import static java.util.logging.Level.SEVERE; +import static javax.security.auth.message.AuthStatus.SEND_SUCCESS; +import static javax.security.auth.message.AuthStatus.SUCCESS; + +import java.io.IOException; +import java.util.Map; +import java.util.logging.Logger; + +import javax.enterprise.inject.spi.CDI; +import javax.naming.InitialContext; +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.message.AuthException; +import javax.security.auth.message.AuthStatus; +import javax.security.auth.message.MessageInfo; +import javax.security.auth.message.MessagePolicy; +import javax.security.auth.message.callback.CallerPrincipalCallback; +import javax.security.auth.message.callback.GroupPrincipalCallback; +import javax.security.auth.message.module.ServerAuthModule; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.javaee7.jaspic.invoke.bean.CDIBean; +import org.javaee7.jaspic.invoke.bean.EJBBean; + +/** + * + * @author Arjan Tijms + * + */ +public class TestServerAuthModule implements ServerAuthModule { + + private final static Logger logger = Logger.getLogger(TestServerAuthModule.class.getName()); + + private CallbackHandler handler; + private Class[] supportedMessageTypes = new Class[] { HttpServletRequest.class, HttpServletResponse.class }; + + + + @Override + public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler, + @SuppressWarnings("rawtypes") Map options) throws AuthException { + this.handler = handler; + } + + @Override + public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException { + + HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage(); + HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage(); + + if ("cdi".equals(request.getParameter("tech"))) { + callCDIBean(response, "validateRequest"); + } else if ("ejb".equals(request.getParameter("tech"))) { + callEJBBean(response, "validateRequest"); + } + + try { + handler.handle(new Callback[] { + new CallerPrincipalCallback(clientSubject, "test"), + new GroupPrincipalCallback(clientSubject, new String[] { "architect" }) + }); + + return SUCCESS; + + } catch (IOException | UnsupportedCallbackException e) { + throw (AuthException) new AuthException().initCause(e); + } + } + + @Override + public Class[] getSupportedMessageTypes() { + return supportedMessageTypes; + } + + @Override + public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException { + + HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage(); + HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage(); + + if ("cdi".equals(request.getParameter("tech"))) { + callCDIBean(response, "secureResponse"); + } else if ("ejb".equals(request.getParameter("tech"))) { + callEJBBean(response, "secureResponse"); + } + + return SEND_SUCCESS; + } + + @Override + public void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException { + + HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage(); + HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage(); + + if ("cdi".equals(request.getParameter("tech"))) { + callCDIBean(response, "cleanSubject"); + } else if ("ejb".equals(request.getParameter("tech"))) { + callEJBBean(response, "cleanSubject"); + } + } + + private void callCDIBean(HttpServletResponse response, String phase) { + try { + CDIBean cdiBean = CDI.current().select(CDIBean.class).get(); + response.getWriter().write(phase + ": " + cdiBean.getText()); + } catch (Exception e) { + logger.log(SEVERE, "", e); + } + } + + private void callEJBBean(HttpServletResponse response, String phase) { + try { + EJBBean ejbBean = (EJBBean) new InitialContext().lookup("java:module/EJBBean"); + response.getWriter().write(phase + ": " + ejbBean.getText()); + } catch (Exception e) { + logger.log(SEVERE, "", e); + } + } + + +} \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/servlet/ProtectedServlet.java b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/servlet/ProtectedServlet.java new file mode 100644 index 000000000..22208d9e6 --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/servlet/ProtectedServlet.java @@ -0,0 +1,26 @@ +package org.javaee7.jaspic.invoke.servlet; +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Arjan Tijms + * + */ +@WebServlet(urlPatterns = "/protected/servlet") +public class ProtectedServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + response.getWriter().write("Resource invoked\n"); + request.logout(); + } + +} \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/servlet/PublicServlet.java b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/servlet/PublicServlet.java new file mode 100644 index 000000000..d245050d9 --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/java/org/javaee7/jaspic/invoke/servlet/PublicServlet.java @@ -0,0 +1,26 @@ +package org.javaee7.jaspic.invoke.servlet; +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Arjan Tijms + * + */ +@WebServlet(urlPatterns = "/public/servlet") +public class PublicServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + response.getWriter().write("Resource invoked\n"); + request.logout(); + } + +} \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/beans.xml b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 000000000..e69de29bb diff --git a/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/glassfish-web.xml b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/glassfish-web.xml new file mode 100644 index 000000000..26559e3f6 --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/glassfish-web.xml @@ -0,0 +1,12 @@ + + + + + + architect + architect + + + + + \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/ibm-application-bnd.xml b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/ibm-application-bnd.xml new file mode 100644 index 000000000..9aa892cbc --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/ibm-application-bnd.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/jboss-web.xml b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/jboss-web.xml new file mode 100644 index 000000000..b6ab7d0ba --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/jboss-web.xml @@ -0,0 +1,5 @@ + + + + jaspitest + diff --git a/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/web.xml b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..ffd58ffa6 --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,20 @@ + + + + + + Test + /protected/* + + + architect + + + + + architect + + + \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeCDIBeanProtectedTest.java b/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeCDIBeanProtectedTest.java new file mode 100644 index 000000000..74cd8c66e --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeCDIBeanProtectedTest.java @@ -0,0 +1,60 @@ +package org.javaee7.jaspictest.invoke; + +import static org.junit.Assert.assertTrue; + +import org.javaee7.jaspic.common.ArquillianBase; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * This tests that a SAM is able to obtain and call a CDI bean when the request is to a protected resource + * (a resource for which security constraints have been set). + * + * @author Arjan Tijms + * + */ +@RunWith(Arquillian.class) +public class InvokeCDIBeanProtectedTest extends ArquillianBase { + + @Deployment(testable = false) + public static Archive createDeployment() { + return tryWrapEAR( + defaultWebArchive() + .addAsWebInfResource(resource("beans.xml")) + ); + } + + @Test + public void protectedInvokeCDIFromValidateRequest() { + String response = getFromServerPath("protected/servlet?tech=cdi"); + + assertTrue( + "Response did not contain output from CDI bean for validateRequest for protected resource. (note: this is not required by the spec)", + response.contains("validateRequest: Called from CDI") + ); + } + + @Test + public void protectedInvokeCDIFromCleanSubject() { + String response = getFromServerPath("protected/servlet?tech=cdi"); + + assertTrue( + "Response did not contain output from CDI bean for cleanSubject for protected resource. (note: this is not required by the spec)", + response.contains("cleanSubject: Called from CDI") + ); + } + + @Test + public void protectedInvokeCDIFromSecureResponse() { + String response = getFromServerPath("protected/servlet?tech=cdi"); + + assertTrue( + "Response did not contain output from CDI bean for secureResponse for protected resource. (note: this is not required by the spec)", + response.contains("secureResponse: Called from CDI") + ); + } + +} \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeCDIBeanPublicTest.java b/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeCDIBeanPublicTest.java new file mode 100644 index 000000000..5f4f2c4d7 --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeCDIBeanPublicTest.java @@ -0,0 +1,60 @@ +package org.javaee7.jaspictest.invoke; + +import static org.junit.Assert.assertTrue; + +import org.javaee7.jaspic.common.ArquillianBase; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * This tests that a SAM is able to obtain and call a CDI bean when the request is to a public resource + * (a resource for which no security constraints have been set). + * + * @author Arjan Tijms + * + */ +@RunWith(Arquillian.class) +public class InvokeCDIBeanPublicTest extends ArquillianBase { + + @Deployment(testable = false) + public static Archive createDeployment() { + return tryWrapEAR( + defaultWebArchive() + .addAsWebInfResource(resource("beans.xml")) + ); + } + + @Test + public void publicInvokeCDIFromValidateRequest() { + String response = getFromServerPath("public/servlet?tech=cdi"); + + assertTrue( + "Response did not contain output from CDI bean for validateRequest for public resource. (note: this is not required by the spec)", + response.contains("validateRequest: Called from CDI") + ); + } + + @Test + public void publicInvokeCDIFromCleanSubject() { + String response = getFromServerPath("public/servlet?tech=cdi"); + + assertTrue( + "Response did not contain output from CDI bean for cleanSubject for public resource. (note: this is not required by the spec)", + response.contains("cleanSubject: Called from CDI") + ); + } + + @Test + public void publicInvokeCDIFromSecureResponse() { + String response = getFromServerPath("public/servlet?tech=cdi"); + + assertTrue( + "Response did not contain output from CDI bean for secureResponse for public resource. (note: this is not required by the spec)", + response.contains("secureResponse: Called from CDI") + ); + } + +} \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeEJBBeanProtectedTest.java b/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeEJBBeanProtectedTest.java new file mode 100644 index 000000000..81d6d0146 --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeEJBBeanProtectedTest.java @@ -0,0 +1,57 @@ +package org.javaee7.jaspictest.invoke; + +import static org.junit.Assert.assertTrue; + +import org.javaee7.jaspic.common.ArquillianBase; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * This tests that a SAM is able to obtain and call an EJB bean when the request is to a protected resource + * (a resource for which security constraints have been set). + * + * @author Arjan Tijms + * + */ +@RunWith(Arquillian.class) +public class InvokeEJBBeanProtectedTest extends ArquillianBase { + + @Deployment(testable = false) + public static Archive createDeployment() { + return defaultArchive(); + } + + @Test + public void protectedInvokeEJBFromValidateRequest() { + String response = getFromServerPath("protected/servlet?tech=ejb"); + + assertTrue( + "Response did not contain output from EJB bean for validateRequest for protected resource. (note: spec is silent on this, but it should work)", + response.contains("validateRequest: Called from EJB") + ); + } + + @Test + public void protectedInvokeEJBFromCleanSubject() { + String response = getFromServerPath("protected/servlet?tech=ejb"); + + assertTrue( + "Response did not contain output from EJB bean for cleanSubject for protected resource. (note: spec is silent on this, but it should work)", + response.contains("cleanSubject: Called from EJB") + ); + } + + @Test + public void protectedInvokeEJBFromSecureResponse() { + String response = getFromServerPath("protected/servlet?tech=ejb"); + + assertTrue( + "Response did not contain output from EJB bean for secureResponse for protected resource. (note: spec is silent on this, but it should work)", + response.contains("secureResponse: Called from EJB") + ); + } + +} \ No newline at end of file diff --git a/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeEJBBeanPublicTest.java b/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeEJBBeanPublicTest.java new file mode 100644 index 000000000..746a61a26 --- /dev/null +++ b/jaspic/invoke-ejb-cdi/src/test/java/org/javaee7/jaspictest/invoke/InvokeEJBBeanPublicTest.java @@ -0,0 +1,57 @@ +package org.javaee7.jaspictest.invoke; + +import static org.junit.Assert.assertTrue; + +import org.javaee7.jaspic.common.ArquillianBase; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * This tests that a SAM is able to obtain and call an EJB bean when the request is to a public resource + * (a resource for which no security constraints have been set). + * + * @author Arjan Tijms + * + */ +@RunWith(Arquillian.class) +public class InvokeEJBBeanPublicTest extends ArquillianBase { + + @Deployment(testable = false) + public static Archive createDeployment() { + return defaultArchive(); + } + + @Test + public void publicInvokeEJBFromValidateRequest() { + String response = getFromServerPath("public/servlet?tech=ejb"); + + assertTrue( + "Response did not contain output from EJB bean for validateRequest for public resource.", + response.contains("validateRequest: Called from EJB") + ); + } + + @Test + public void publicInvokeEJBFromCleanSubject() { + String response = getFromServerPath("public/servlet?tech=ejb"); + + assertTrue( + "Response did not contain output from EJB bean for cleanSubject for public resource.", + response.contains("cleanSubject: Called from EJB") + ); + } + + @Test + public void publicInvokeEJBFromSecureResponse() { + String response = getFromServerPath("public/servlet?tech=ejb"); + + assertTrue( + "Response did not contain output from EJB bean for secureResponse for public resource.", + response.contains("secureResponse: Called from EJB") + ); + } + +} \ No newline at end of file diff --git a/jaspic/pom.xml b/jaspic/pom.xml index 682cf169e..b31a8436e 100644 --- a/jaspic/pom.xml +++ b/jaspic/pom.xml @@ -8,37 +8,40 @@ 1.0-SNAPSHOT ../pom.xml - org.javaee7 + jaspic - 1.0-SNAPSHOT pom + Java EE 7 Sample: jaspic common - - - async-authentication basic-authentication - - - ejb-propagation + + + custom-principal lifecycle + + wrapping + register-session - - - wrapping + + + async-authentication @@ -48,10 +51,14 @@ this is indeed possible by using Servlets that are injected with a CDI bean and JSF views. --> dispatching-jsf-cdi - - custom-principal + + ejb-propagation + + + invoke-ejb-cdi