14 Replies Latest reply on Apr 13, 2005 8:54 AM by thomas.diesler

    EJB endpoint authentication and authorization

    pvainio

      Hi,

      Is there a way to authenticate and authorize EJB endpoint ws users against jaas? This information is missing in JbossWS wiki.

        • 1. XDoclet 1.2.2 & JBoss 3.2.6 incompatability, which is correc

          I'm using the above version of XDoclet with a session bean. But, JBoss and XDoclet don't seem to agree on the ejb-jar deployment descriptor doctype. My build script looks like :

          <ejbdoclet
           destdir="${genjava.dir}"
           excludedtags="@version,@author"
           addedtags="@xdoclet-generated at ${TODAY}"
           verbose="true"
           ejbspec="2.0" >
          
           <fileset dir="${java.dir}">
           <include name="**/*Bean.java"/>
           </fileset>
          
           <dataobject/>
          
           <packageSubstitution packages="persistence" substituteWith="interfaces"/>
          
           <remoteinterface pattern="{0}Remote"/>
           <localinterface pattern="{0}"/>
          
           <homeinterface />
           <localhomeinterface/>
          
           <entitypk/>
           <entitycmp/>
          
           <deploymentdescriptor
           destdir="${gendeploy.dir}/META-INF"
           description="SSO Beans"
           displayname="SSO Beans"
           validatexml="true"/>
          
           <jboss version="3.2"
           securityDomain="java:/jaas/samples"
           preferredRelationMapping="relation-table"
           datasource="java:/DefaultDS"
           datasourcemapping="Hypersonic SQL"
           destdir="${gendeploy.dir}/META-INF" />
          
          </ejbdoclet>
          


          XDoclet generates the following DOCTYPE for ejb-jar.xml:

          <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">


          When I deploy this, JBoss ignores it, giving the following message:

          15:40:16,096 DEBUG [JARDeployer] No META-INF or WEB-INF resource found, assuming it if for us


          If I manually change the DOCTYPE to the following:

          <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtds/ejb-jar_2_0.dtd">


          it works correctly. Notice, the change was from 'dtd' to 'dtds' in the URL. Which is correct? And how do i resolve the discrepancy?

          Any help would be greatly appreciated,
          Michael


          • 2. Re: EJB endpoint authentication and authorization
            thomas.diesler

            Yes there is. I'll write about it shortly. Hava a look at the jboss_4_0.dtd

            • 3. Re: EJB endpoint authentication and authorization

              Concerning this, I have secured my EJB-webservice-endpoint using the regular J2EE way (method permissions in ejb-jar.xml).

              The thing is I can not authenticate to access this web service. I have tried the basic Java Authenticator or the more advanced LoginContext/CallBackHandler (ok, this is for secured EJB calss) ; but none of these has authenticated me.

              I am certainly blowing up something here: any pointer welcome...

              David

              • 4. Re: EJB endpoint authentication and authorization
                thomas.diesler
                • 5. Re: EJB endpoint authentication and authorization

                  Hi Thomas - Thanks for the information.

                  With the code you propose, I still have the same exception (see after) : it seems that the principal is not forwarded to the EJB.

                  Of course, it is always suspicious when someone says "I did as you said but it does not work" ;-) But this is what I did!

                  FYI: I used jbossall-client.jar (from JB4) and axis-1.1.jar : is this okay?

                  Thanks.
                  David

                  AxisFault
                   faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Client
                   faultSubcode:
                   faultString: MBeanException: null Cause: java.rmi.ServerException: EJBException:; nested exception is:
                   javax.ejb.EJBException: checkSecurityAssociation; CausedByException is:
                   Authentication exception, principal=null
                   faultActor:
                   faultNode:
                   faultDetail:
                   {http://xml.apache.org/axis/}stackTrace: AxisFault
                   faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Client
                   faultSubcode:
                   faultString: MBeanException: null Cause: java.rmi.ServerException: EJBException:; nested exception is:
                   javax.ejb.EJBException: checkSecurityAssociation; CausedByException is:
                   Authentication exception, principal=null
                   faultActor:
                   faultNode:
                   faultDetail:
                  
                  MBeanException: null Cause: java.rmi.ServerException: EJBException:; nested exception is:
                   javax.ejb.EJBException: checkSecurityAssociation; CausedByException is:
                   Authentication exception, principal=null
                   at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:260)
                   at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:169)
                   at org.apache.axis.encoding.DeserializationContextImpl.endElement(DeserializationContextImpl.java:1015)
                   at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                   at org.apache.crimson.parser.Parser2.content(Unknown Source)
                   at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                   at org.apache.crimson.parser.Parser2.content(Unknown Source)
                   at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                   at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
                   at org.apache.crimson.parser.Parser2.parse(Unknown Source)
                   at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
                   at javax.xml.parsers.SAXParser.parse(Unknown Source)
                   at org.apache.axis.encoding.DeserializationContextImpl.parse(DeserializationContextImpl.java:242)
                   at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:538)
                   at org.apache.axis.Message.getSOAPEnvelope(Message.java:376)
                   at org.apache.axis.client.Call.invokeEngine(Call.java:2583)
                   at org.apache.axis.client.Call.invoke(Call.java:2553)
                   at org.apache.axis.client.Call.invoke(Call.java:2248)
                   at org.apache.axis.client.Call.invoke(Call.java:2171)
                   at org.apache.axis.client.Call.invoke(Call.java:1691)
                   at org.apache.axis.client.AxisClientProxy.invoke(AxisClientProxy.java:186)
                   at $Proxy0.getContactInfo(Unknown Source)
                   at SecuredWSClient.<init>(SecuredWSClient.java:21)
                   at Main.<init>(Main.java:4)
                   at Main.main(Main.java:24)
                  
                  




                  • 6. Re: EJB endpoint authentication and authorization
                    thomas.diesler

                    axis-1.1.jar is not ok. JBossWS uses a modified version of axis-1.1 that adds J2EE specific functionality to axis, like BasicProfile-1.0 complientcy. The jboss-ws4ee.sar contains the axis-ws4ee.jar. That is the only valid axis version to be used with JBossWS.

                    Turn on axis debug level on the client side. Make sure the headers are put in the soap message. If not, check if the ClientLoginHandler is executed as part of client side axis handler chain.
                    If you see the headers in the message make sure the ServerLoginHandler is excuted on the server side, it should set the principal/credential in the SecurityAssociation.

                    See webservice/samples/server-sec in jboss-head for a working implementation. The sample is not yet ported to the jboss-4.0 branch.

                    • 7. Re: EJB endpoint authentication and authorization

                      > axis-ws4ee.jar. That is the only valid axis version to be used

                      I was afraid you would say that! It is the first thing I tried but I got strange configuration related error messages, so I tried another axis lib.

                      Anyway, thanks for pointing me to the right tools, I will certainly have this running soon now.

                      D.

                      • 8. Re: EJB endpoint authentication and authorization

                        Well, I was too confident in my last post: following your instruction, I clearly see in the logs that the generated SOAP message does not contain any header:

                        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                         <soapenv:Body soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                         <ns1:getContactInfo xmlns:ns1="http://ec.ep.dit.isp.tests/ws4ee">
                         <in0 xsi:type="xsd:string">mafia</in0>
                         </ns1:getContactInfo>
                         </soapenv:Body>
                        </soapenv:Envelope>

                        So I think that I have to follow your advice:
                        If not, check if the ClientLoginHandler is executed as part of client side axis handler chain.

                        though I do not know how to be sure of that. In the log, I can not find any entry coming from a class named "ClientLoginHandler".

                        Is there a specific configuration of Axis to use to achieve that?

                        Thanks for your reply,
                        David

                        BTW. I looked at webservice/samples/server-sec and followed the test case to also ensure that the EJB responds correctly & can authenticate when called on his remote.


                        • 9. Re: EJB endpoint authentication and authorization
                          wejaeger

                          hi all,

                          I'm not sure, but I think you guys forgot to add a port-component tag in jboss.xml:

                          <jboss>
                           <security-domain>java:/jaas/other</security-domain>
                           <enterprise-beans>
                           <session>
                           <ejb-name>ServiceActivationLocal</ejb-name>
                           <local-jndi-name>com.tsi.iplsprovisioning.services/ServiceActivation/LocalHome</local-jndi-name>
                           <port-component>
                           <port-component-name>ServiceActivation</port-component-name>
                           <port-uri>/sa</port-uri>
                           <auth-method>BASIC</auth-method>
                           </port-component> </session>
                           </enterprise-beans>
                          </jboss>


                          After adding this it worked.

                          Regards

                          Werner


                          • 10. Re: EJB endpoint authentication and authorization

                            Dear Werner,

                            Thanks for your post. I have changed jboss.xml according to your suggestion and, yes, it changes something!

                            Now I get a regular HTTP 401 error when calling the web service.

                            Great stuff, except that I do not know how to authenticate: neither my Java default Authenticator or stub._setProperty seem to be taken in account.

                            How do you authenticate from clients?

                            Thanks,
                            David

                            • 11. Re: EJB endpoint authentication and authorization
                              wejaeger

                              Dear David,

                              here is a code fragment from my junit test case:

                              public void testJAXRPCBinding() throws Exception
                               {
                               final Service service = ServiceFactory.newInstance().createService(m_WsdldUrl, SERVICEQN);
                               final _DAMONA_INFO message = new _DAMONA_INFO();
                               final ConfigurationMessage cnfgMessage = new ConfigurationMessage();
                               final SapInfo sapInfo = new SapInfo();
                               final SapId sapId = new SapId();
                               final VpnId vpnId = new VpnId("0123456789");
                               final SapNo sapNo = new SapNo("123456");
                               final IServiceActivationRemote endpoint = (IServiceActivationRemote)service.getPort(IServiceActivationRemote.class);
                              
                               final String[] astrUserInfo = m_WsdldUrl.getUserInfo().split(":");
                               if (astrUserInfo != null && astrUserInfo.length > 0)
                               {
                               ((Stub)endpoint)._setProperty(Stub.USERNAME_PROPERTY, astrUserInfo[0]);
                               if (astrUserInfo.length == 2)
                               ((Stub)endpoint)._setProperty(Stub.PASSWORD_PROPERTY, astrUserInfo[1]); }
                              
                               sapId.setVPN_ID(vpnId);
                               sapId.setSAP_NO(sapNo);
                               sapInfo.setSAP_ID(sapId);
                               cnfgMessage.setSAP_INFO(new SapInfo[] { sapInfo });
                               message.setCONFIGURATION_MESSAGE(cnfgMessage);
                              
                               final _DAMONA_INFO returnMsg = endpoint.processMessage(message);
                              .
                              .
                              .
                              


                              The authentication related code is bold.

                              In case you are using the java:/jaas/other domain, have you put roles.properties and user.properties into the conf/ directory ?

                              Hope his helps a bit...

                              Regards

                              Werner

                              • 12. Re: EJB endpoint authentication and authorization
                                thomas.diesler

                                BASIC authentication is on the transport level. It is an alternative to message based authentication, which is transport independent.

                                To set the username/password for BASIC authentication, you still use

                                 Stub stub = (Stub)endpoint;
                                 stub._setProperty(Stub.USERNAME_PROPERTY, USERNAME);
                                 stub._setProperty(Stub.PASSWORD_PROPERTY, PASSWORD);
                                


                                as described in the wiki.

                                You may want to checkout jboss-head and run the server-sec test case like this:

                                 cd webservice/samples/server-sec
                                 ant -Dserver=default deploy
                                 ant test
                                


                                All four tests should pass.


                                • 13. Re: EJB endpoint authentication and authorization
                                  jtroxel

                                  I have a similar problem. HTTP Basic auth seems to be configured correctly and tests setting a username and password on the Stub work, but only if I use a local WSDL. I think the problem is that the http://blah:8080/ejb-jar/port-component?wsdl call also requires credentials with basic auth.

                                  There doesn't seem to be a createService on ServiceFactoryImpl that sets these. Nor can I get it to work by stuffing the credentials into the ?wsdl url, not that that would be a good solution.

                                  Is there a way to send credentials when getting the wsdl, or alternatively a way to configure the web service to let only those call be anonymous? Thanks much

                                  - John

                                  • 14. Re: EJB endpoint authentication and authorization
                                    thomas.diesler

                                    On the server side you have the option to specify an alternative <wsdl-publish-location> which can be served by a context that does not have security restrictions.

                                    If the client/server have a fixed contract, there is little benefit of obtaining the WSDL from the server every time the client creates a Service.