5 Replies Latest reply on Jul 14, 2004 4:59 PM by ceasaros

    EJB Security

    elaineqs

      Hi,
      I'm tring to implemente EJB security using the following files with JBoss 3.2.3:
      login-config.xml
      ....
      <application-policy name = "framework">

      <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
      flag = "required" />

      </application-policy>
      ....
      ____________________
      users.properties
      admin=password
      ____________________
      roles.properties
      admin=teste
      _________________________
      ejb-jar.xml
      .....
      <display-name>testeejb</display-name>
      <enterprise-beans>

      <ejb-name>TesteBean</ejb-name>
      core.ejb.TesteBeanHome
      core.ejb.TesteBean
      <ejb-class>core.ejb.TesteBeanEJB</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>

      </enterprise-beans>
      <assembly-descriptor>
      <security-role>
      Teste user
      <role-name>teste</role-name>
      </security-role>
      <method-permission>
      <role-name>teste</role-name>

      <ejb-name>TesteBean</ejb-name>
      <method-intf>Home</method-intf>
      <method-name>create</method-name>

      </method-permission>
      </assembly-descriptor>
      </ejb-jar>
      _______________________
      jboss.xml
      ....

      <security-domain>java:/jaas/framework</security-domain>
      <enterprise-beans>

      <ejb-name>TesteBean</ejb-name>
      <jndi-name>TesteBean</jndi-name>

      </enterprise-beans>

      _________________________
      login.jsp



      Username:
      Password:




      _____________________________
      login.java (Servlet Login)

      ...
      public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      try {
      UsernamePassworkHandler uph = new UsernamePassworkHandler((String) req.getParameter("username"), ((String) req.getParameter("password")).toCharArray()); (I implemented this class)
      LoginContext lc = new LoginContext("framework", uph);
      lc.login();
      System.out.println("Successful Loggin");

      Subject s = lc.getSubject();
      System.out.println(s.toString());

      // Try to access a protected EJB (only user teste can access the create method)
      InitialContext ctx = new InitialContext();
      TesteBeanHome home = (TesteBeanHome) ctx.lookup("TesteBean");
      TesteBean bean = (TesteBean) home.create();
      bean.writeText();
      } catch (Exception e) {
      e.printStackTrace();
      }
      } ...
      _________________________________

      Using those files, i got the following exception:


      16:19:42,612 INFO [STDOUT] Successful Loggin
      16:19:42,616 INFO [STDOUT] Subject:
      Principal: admin
      Principal: Roles(members:teste)
      16:19:42,633 ERROR [SecurityInterceptor] Authentication exception, principal=null
      16:19:42,634 ERROR [LogInterceptor] EJBException, causedBy:
      java.lang.SecurityException: Authentication exception, principal=null
      at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:164)
      at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:81)
      at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:120)
      at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:93)
      at org.jboss.ejb.StatelessSessionContainer.internalInvokeHome(StatelessSessionContainer.java:319)
      at org.jboss.ejb.Container.invoke(Container.java:720)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:324)
      at org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284)
      at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
      at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:101)
      at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:90)
      at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
      at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45)
      at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:173)
      at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
      at $Proxy33.create(Unknown Source)
      at login.doGet(login.java:35)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:220)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2417)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
      at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
      at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
      at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
      at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:197)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:781)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:549)
      at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
      at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
      at java.lang.Thread.run(Thread.java:534)
      _________________________________

      What is missing to my application?? I don't want to use web application authentication. I want to use only EJB security. Is this possible?

      Many thanks!

        • 1. Re: EJB Security
          ceasaros

          You perform the authentication / authorization within the web application environment and not in the ejb application environment. So your principal is only available inside your webserver (tomcat) and not in the ejb application environment.

          If you don't want security in your webapplication how do you want to retieve the username/password? In you example you still use a login.jsp which comes from your webapplication I suppose. So why not just use the j_security_check then your Principal is both available in the web and ejb environment. Otherwise take a look at the source code of JBossSecurityMngRealm.java cause this is the realm that couples Tomcat to JBoss.

          • 2. Re: EJB Security
            elaineqs


            Thanks for your reply!

            Yes, the login.jsp is from my web application. I wouldn't like to authenticate through web application because i have to specify the LoginModule at the deployment descriptor. This is a problem to my application because it can authenticate users with diferent databases. Depending upon the database (datasource) id (i will pass this id as a servlet parameter), the servlet should get the id and identify the loginModule to use. For example: if the database id is 001, the servlet authenticate users with DS1 (application-policy=framework), and if the id is 002, the servlet uses DS2 (application-policy=framework2) but it decides what application policy to use at runtime. Using the login inside the servlet, i can set the name to LoginModule.....but, i have the problem you stated: my login is only for web container.... Isn' t there a way to authenticate ejb independently from the web application??
            Anyway, I will see the JBossSecurityMngRealm.java.

            Thanks again!


            • 3. Re: EJB Security
              auckyboy

              Is there no way to explicitly set the principal in the ejb tier..i.e. set credentials in the context

              p.put(Context.SECURITY_PRINCIPAL, "admin");
              p.put(Context.SECURITY_CREDENTIALS, "adminpass");

              or some other way ?

              • 4. Re: EJB Security
                auckyboy

                fixed

                • 5. Re: EJB Security
                  ceasaros

                  Maybe it's possible for you to use a filter instead of a servlet. (servlet2.3 specs). The filter is always executed before handling the request in a servlet. I though you can filter you're request before it's authenticated by Tomcat/JBoss but than again I think the authentication is executed before the filter so it wouldn't help, but maybe you can use it. I think it's worth looking at.