title: Unable to authenticate with jax-ws on Glassfish
body: <p>I have been trying to create a java service that uses basic authentication over SSL.  Configuring the SSL was quite simple but configuring authentication is much more of a problem.  Any time I try to call a method marked with a @RolesAllowed annotation I receive the following exception...</p>
  
  <pre><code>Exception in thread "AWT-EventQueue-0" javax.xml.ws.soap.SOAPFaultException: javax.ejb.EJBAccessException
  at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178)
  at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:111)
  at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:108)
  at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
  at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:129)
  at $Proxy30.reverseString(Unknown Source)
  at securitytestclient.SecurityTestClient.reverseStringSOAP(SecurityTestClient.java:305)
  at securitytestclient.SecurityTestClient.buttonReverseActionPerformed(SecurityTestClient.java:217)
  at securitytestclient.SecurityTestClient.access$000(SecurityTestClient.java:20)
  at securitytestclient.SecurityTestClient$1.actionPerformed(SecurityTestClient.java:72)
  at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
  at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
  at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
  at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
  at javax.swing.plaf.basic.BasicButtonListener$Actions.actionPerformed(BasicButtonListener.java:303)
  at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1661)
  at javax.swing.JComponent.processKeyBinding(JComponent.java:2879)
  at javax.swing.JComponent.processKeyBindings(JComponent.java:2926)
  at javax.swing.JComponent.processKeyEvent(JComponent.java:2842)
  at java.awt.Component.processEvent(Component.java:6282)
  at java.awt.Container.processEvent(Container.java:2229)
  at java.awt.Component.dispatchEventImpl(Component.java:4861)
  at java.awt.Container.dispatchEventImpl(Container.java:2287)
  at java.awt.Component.dispatchEvent(Component.java:4687)
  at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1890)
  at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:752)
  at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1017)
  at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:889)
  at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:717)
  at java.awt.Component.dispatchEventImpl(Component.java:4731)
  at java.awt.Container.dispatchEventImpl(Container.java:2287)
  at java.awt.Window.dispatchEventImpl(Window.java:2713)
  at java.awt.Component.dispatchEvent(Component.java:4687)
  at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
  at java.awt.EventQueue.access$000(EventQueue.java:101)
  at java.awt.EventQueue$3.run(EventQueue.java:666)
  at java.awt.EventQueue$3.run(EventQueue.java:664)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
  at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
  at java.awt.EventQueue$4.run(EventQueue.java:680)
  at java.awt.EventQueue$4.run(EventQueue.java:678)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
  at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
  at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
  at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
  at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
  at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
  at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
  at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
  </code></pre>
  
  <p>My server is using JavaEE on Glassfish 3.  It's functions are defined in a bean as follows...</p>
  
  <pre><code>package com.intproimp.testing.beans;
  
  import javax.annotation.security.PermitAll;
  import javax.annotation.security.RolesAllowed;
  import javax.ejb.Local;
  import javax.ejb.Stateless;
  
  @Stateless(mappedName="ejb/StringOps/Bean")
  @Local(StringOps.class)
  public class StringOpsBean implements StringOps {
  
      @PermitAll
      @Override
      public String echoString(String str) {
          return str;
      }
  
      @RolesAllowed({"admin"})
      @Override
      public String reverseString(String str) {
          char[] input = str.toCharArray();
          char[] output = new char[input.length];
          for (int i = 0; i &lt; output.length; i++) {
              output[i] = input[input.length - i - 1];
          }
          return new String(output);
      }
  }
  </code></pre>
  
  <p>I have added the login config to my web.xml file...</p>
  
  <pre><code>&lt;login-config&gt;
      &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
      &lt;realm-name&gt;testing-frealm&lt;/realm-name&gt;
  &lt;/login-config&gt;
  &lt;security-role&gt;
      &lt;description/&gt;
      &lt;role-name&gt;admin&lt;/role-name&gt;
  &lt;/security-role&gt;
  &lt;security-role&gt;
      &lt;description/&gt;
      &lt;role-name&gt;user&lt;/role-name&gt;
  &lt;/security-role&gt;
  </code></pre>
  
  <p>The security realm is just a file realm with one user(name: "andrew", pass: "12345").
  I've also added the role-group mappings to my glassfish-web.xml</p>
  
  <pre><code>&lt;security-role-mapping&gt;
      &lt;role-name&gt;user&lt;/role-name&gt;
      &lt;group-name&gt;user&lt;/group-name&gt;
  &lt;/security-role-mapping&gt;
  &lt;security-role-mapping&gt;
      &lt;role-name&gt;admin&lt;/role-name&gt;
      &lt;group-name&gt;admin&lt;/group-name&gt;
  &lt;/security-role-mapping&gt;
  </code></pre>
  
  <p>On the client side, I have a simple swing application to test from...</p>
  
  <p><img src="https://i.stack.imgur.com/DZdU4.png" alt="Swing Test Application"></p>
  
  <p>The call being made is to the reverse function on a SOAP channel.  The SOAP client components are generated with NetBeans via the New->WebService Client function.  And the action associated with the reverse button click is...</p>
  
  <pre><code>private void addAuthenticateionSOAP(StringOpsSOAP port) {
      ((BindingProvider) port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, fieldUsername.getText());
      ((BindingProvider) port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, fieldPassword.getText());
  }
  
  private String reverseStringSOAP(String str) {
      StringOpsSOAP_Service service = new StringOpsSOAP_Service();
      StringOpsSOAP port = service.getStringOpsSOAPPort();
      if (checkAuthentication.isSelected()) addAuthenticateionSOAP(port);
      return port.reverseString(str);
  }
  </code></pre>
  
  <p>I'm sure there is just some little thing that I'm missing, but I've been looking at the problem for days and still haven't found it.</p>
  
  <p>-- Edit -- 
  I realized there might be some confusion since I didn't post my WebService code.  The EJB that contains the String functions is accessed through a SOAP WebService Bean...</p>
  
  <pre><code>package com.intproimp.test.web;
  
  import com.intproimp.test.beans.StringOps;
  import javax.ejb.EJB;
  import javax.jws.WebService;
  import javax.ejb.Stateless;
  import javax.jws.WebMethod;
  import javax.jws.WebParam;
  
  @WebService(serviceName = "StringOpsSOAP")
  @Stateless()
  public class StringOpsSOAP {
  
      @EJB
      private StringOps ops;
  
      @WebMethod(operationName = "echoString")
      public String echoString(@WebParam(name = "str") String str) {
          return ops.echoString(str);
      }
  
      @WebMethod(operationName = "reverseString")
      public String reverseString(@WebParam(name = "str") String str) {
          return ops.reverseString(str);
      }
  }
  </code></pre>