glassfish
  1. glassfish
  2. GLASSFISH-16236

RunAs does not propagate Identity from Servlet.init

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.1_b43
    • Fix Version/s: 4.0_b71
    • Component/s: security, web_container
    • Labels:
      None
    • Environment:

      java version "1.6.0_23"
      Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
      Java HotSpot(TM) 64-Bit Server VM (build 19.0-b09, mixed mode)

      Description

      Calls to Injected EJB in a Servlet are not propagated when calling the EJB from init.
      Per Servlet Spec Appendix 8:
      "Clarification: "run-as" identity must apply to all calls from a servlet including
      init() and destroy() (12.7)"

      See forum discussion http://www.java.net/forum/topic/glassfish/glassfish/security-identity-propogation-servlet-runas?force=641

      See attached Example Application EAR. The example application deploys an ejb and web module.

      The EJB module deploys 2 beans:

      package runasejb;

      import javax.annotation.Resource;
      import javax.annotation.security.DeclareRoles;
      import javax.annotation.security.PermitAll;
      import javax.ejb.SessionContext;
      import javax.ejb.Stateless;

      /**

      • The RunAsEJB is declares SystemRole as a used role. This is defined
      • in the application.xml and sun-application.xml. The EJB has two methods
      • to return the string value of the caller principal and boolean value
      • if the caller has SystemRole
      • @author joel@stewbeans.com
        */
        @Stateless
        @DeclareRoles("SystemRole")
        @PermitAll
        public class RunAsEJB
        {

      @Resource
      SessionContext context;

      public String getCallerPrincipal()

      { return context.getCallerPrincipal().getName(); }

      public boolean isCallerInSystemRole(){ return context.isCallerInRole("SystemRole"); }
      }



      package runasejb;

      import javax.annotation.Resource;
      import javax.annotation.security.DeclareRoles;
      import javax.annotation.security.PermitAll;
      import javax.ejb.SessionContext;
      import javax.ejb.Stateless;

      /**
      * The RunAsEJB declares SystemRole as a used role. This is defined
      * in the application.xml and sun-application.xml. The EJB has two methods
      * to return the string value of the caller principal and boolean value
      * if the caller has SystemRole
      * @author joel@stewbeans.com
      */
      @Stateless
      @DeclareRoles("SystemRole")
      @PermitAll
      public class RunAsEJB
      {

      @Resource
      SessionContext context;

      public String getCallerPrincipal()
      { return context.getCallerPrincipal().getName(); }

      public boolean isCallerInSystemRole()

      { return context.isCallerInRole("SystemRole"); }

      }

      The Web Module has servlet:

      package runastest;

      import java.io.IOException;
      import java.util.logging.Logger;
      import javax.annotation.PostConstruct;
      import javax.annotation.security.RunAs;
      import javax.ejb.EJB;
      import javax.servlet.ServletContextEvent;
      import javax.servlet.ServletContextListener;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import runasejb.RunAsEJB;

      /**

      • The StartupServlet declares runas SystemRole. The
      • injected TestRunAsEJB should be passed the SystemRole identity as
      • configured in the web.xml / sun-web.xml
      • @author joel@stewbeans.com
        */
        @RunAs("SystemRole")
        public class StartupServlet extends HttpServlet implements ServletContextListener{

      Logger log = Logger.getLogger(StartupServlet.class.getName());

      @EJB
      RunAsEJB runAsEJB;

      @Override
      public void contextInitialized(ServletContextEvent sce)

      { log.info("In StartupServlet contextInitialized()"); }

      @PostConstruct
      public void postConstruct()

      { log.info("In StartupServlet postConstruct()"); }

      /**

      • Init is called after &PostConstruct and ServletContextListener Context initialized.
        */
        public void init(){
        log.info("In StartupServlet init()");

      String val = runAsEJB.getCallerPrincipal();

      if ("SystemUser".equals(val))

      { log.info("StartupServlet propagates SystemUser Principal."); }

      else

      { log.warning("StartupServlet did NOT propagate SystemUser Principal."); }

      if (runAsEJB.isCallerInSystemRole())

      { log.info("StartupServlet propogates SystemRole Role."); }

      else

      { log.warning("StartupServlet did NOT propagate SystemRole Role"); }

      }

      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{

      log.info("In StartupServlet doGet()");

      String val = runAsEJB.getCallerPrincipal();

      if ("SystemUser".equals(val))

      { log.info("StartupServlet.doGet() propagates SystemUser Principal."); }

      else

      { log.warning("StartupServlet.doGet() did NOT propagate SystemUser Principal."); }

      if (runAsEJB.isCallerInSystemRole())

      { log.info("StartupServlet.doGet() propogates SystemRole Role."); }

      else

      { log.warning("StartupServlet.doGet() did NOT propagate SystemRole Role"); }

      }

      @Override
      public void contextDestroyed(ServletContextEvent sce)
      {

      }
      }

      The Web Module has deployment descriptors:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

      <listener>
      <listener-class>runastest.StartupServlet</listener-class>
      </listener>

      <servlet>
      <servlet-name>RunAsTest</servlet-name>
      <servlet-class>runastest.StartupServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
      </servlet>

      <servlet-mapping>
      <servlet-name>RunAsTest</servlet-name>
      <url-pattern>/*</url-pattern>
      </servlet-mapping>

      <!-- Form authentication configuration parameters -->
      <login-config>
      <auth-method>FORM</auth-method>
      <realm-name>admin-realm</realm-name>
      </login-config>

      <security-role>
      <description/>
      <role-name>SystemRole</role-name>
      </security-role>

      </web-app>

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
      <sun-web-app error-url="">
      <context-root>/RunAsTestEar-war</context-root>
      <class-loader delegate="true"/>
      <jsp-config>
      <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
      </property>
      </jsp-config>
      </sun-web-app>

      (note the security-role-mapping is defined in application.xml - addign to sun-web.xml as well makes no difference)

      The application has descriptors
      <?xml version="1.0" encoding="UTF-8"?>
      <application version="6" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd">
      <display-name>RunAsTest</display-name>
      <module>
      <ejb>RunAsTestEar-ejb.jar</ejb>
      </module>
      <module>
      <web>
      <web-uri>RunAsTestEar-war.war</web-uri>
      <context-root>runastest</context-root>
      </web>
      </module>
      <security-role>
      <role-name>SystemRole</role-name>
      </security-role>
      </application>

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE sun-application PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Java EE Application 6.0//EN" "http://www.sun.com/software/appserver/dtds/sun-application_6_0-0.dtd">
      <sun-application>
      <security-role-mapping>
      <role-name>SystemRole</role-name>
      <principal-name>SystemUser</principal-name>
      </security-role-mapping>
      <realm>admin-realm</realm>
      </sun-application>

      Startup Logging Output:
      WARNING: Realm admin-realm: com.sun.enterprise.security.auth.realm.NoSuchUserException: No such user [SystemUser].
      WARNING: Realm admin-realm: com.sun.enterprise.security.auth.realm.NoSuchUserException: No such user [SystemUser].
      WARNING: DPL8019: The run-as principal SystemUser was assigned by the deployment system based on the specified role. Please consider defining an explicit run-as principal in the sun-specific deployment descriptor.
      WARNING: DPL8019: The run-as principal SystemUser was assigned by the deployment system based on the specified role. Please consider defining an explicit run-as principal in the sun-specific deployment descriptor.
      INFO: Portable JNDI names for EJB RunAsEJB : [java:global/RunAsTestEar/RunAsTestEar-ejb/RunAsEJB, java:global/RunAsTestEar/RunAsTestEar-ejb/RunAsEJB!runasejb.RunAsEJB]
      INFO: Portable JNDI names for EJB SingletonEJB : [java:global/RunAsTestEar/RunAsTestEar-ejb/SingletonEJB, java:global/RunAsTestEar/RunAsTestEar-ejb/SingletonEJB!runasejb.SingletonEJB]
      WARNING: Realm admin-realm: com.sun.enterprise.security.auth.realm.NoSuchUserException: No such user [SystemUser].
      WARNING: Realm admin-realm: com.sun.enterprise.security.auth.realm.NoSuchUserException: No such user [SystemUser].
      INFO: In SingletonEJB PostConstruct
      INFO: SingletonEJB propagates SystemUser Principal.
      INFO: SingletonEJB propogates SystemRole Role.
      INFO: In StartupServlet postConstruct()
      INFO: In StartupServlet contextInitialized()
      INFO: In StartupServlet postConstruct()
      INFO: In StartupServlet init()
      WARNING: StartupServlet did NOT propagate SystemUser Principal.
      WARNING: StartupServlet did NOT propagate SystemRole Role
      INFO: WEB0671: Loading application RunAsTestEar#RunAsTestEar-war.war at [runastest]
      INFO: RunAsTestEar was successfully deployed in 551 milliseconds.

      Access the Servlet get method at /runastest and you will see output:
      INFO: In StartupServlet doGet()
      INFO: StartupServlet.doGet() propagates SystemUser Principal.
      INFO: StartupServlet.doGet() propogates SystemRole Role.

      CONCLUSION:
      1_ Caller identity IS propagated from the Startup EJB post construct.
      2_ The Servlet init method does NOT propagate the caller identity !!!!BUG!!!!
      3_ Caller identity IS propagated from Servlet Get (telling me the configuration is correct).
      4_ (also - the PostConstruct on the servlet is called twice BUG)

        Activity

        No work has yet been logged on this issue.

          People

          • Assignee:
            jazheng
            Reporter:
            joelstewart
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: