4 Replies Latest reply on Jul 26, 2014 9:35 AM by auth.gabor

    Websocket Auth

    max_kuffs

      Hello,

       

      I have a simple Websocket which is protected with a security constraint in the web.xml.

      Connection works like a charm and the Session Parameter of the callback methods has the correct user, BUT when I call an EJB the credentials are not propagated! Is that normal?

       

      @Stateless

      @ServerEndpoint("/ws/hq")

      public class HqWSEndpoint {

          private static final Logger log = LoggerFactory

                  .getLogger(HqWSEndpoint.class);

          private static final ConcurrentLinkedQueue<Session> sessions = new ConcurrentLinkedQueue<Session>();

        

          private static final CloseReason CLOSE_REASON = new CloseReason(CloseCodes.VIOLATED_POLICY, "Auth required!");

        

          @EJB

          private PlayerService playerService;

        

          @OnOpen

          public void onOpen(Session session, EndpointConfig conf) {

              String username = getUsername(session);

              log.info("Connected User: {} with Session {}", username,

                      getSessionId(session)); // logs out the correct username

                

                  return;

              }

              sessions.add(session);

       

              playerService.getCurrentUsername(); // and here i always get anonymous

          ...

        }

      }

      In the getCurrentUsername() I only do:

      @EJB

      public PlayerService {

      @Resource
        
      private SessionContext ctx;


      ...


      Principal callerPrincipal = ctx.getCallerPrincipal();
      if(callerPrincipal == null) {
        
      return null;
      }

      return callerPrincipal.getName();


      Is that maybe a bug? Shouldn't the credentials be propagated to the EJB container like the servlet container does? Note my endpoint is already an EJB.


      greetings,

      m

        • 1. Re: Websocket Auth
          jaikiran

          Is your EJB secured? What happens if you add:

           

          import org.jboss.ejb3.annotation.SecurityDomain;
          
          @SecurityDomain("name-of-your-security-domain")
          ...
          public class PlayerService {
          .....
          }
          
          • 2. Re: Websocket Auth
            max_kuffs

            Tried the SecurityDomain on both Endpoint EJB and PlayerService EJB. No difference. That is quite odd.

             

            The Rest Services work without a problem and the user is well known in the application. No @SecurityDomain needed and it obeys the @RolesAllowed("USER") annotation. Should I file a bug or any config entry we could check?

            • 3. Re: Websocket Auth
              max_kuffs

              I also tried a manual login. More details at stackoverflow: http://stackoverflow.com/questions/23381313/javaee-logincontext

               

              But once an anonymous user there was no way to change that even when the subject proves a correct login. Maybe I have something miss-configured?

              This would be my standalone.xml:

               

              <?xml version="1.0" ?>

               

              <server xmlns="urn:jboss:domain:2.1">

               

                  <extensions>

                      <extension module="org.jboss.as.clustering.infinispan"/>

                      <extension module="org.jboss.as.connector"/>

                      <extension module="org.jboss.as.deployment-scanner"/>

                      <extension module="org.jboss.as.ee"/>

                      <extension module="org.jboss.as.ejb3"/>

                      <extension module="org.jboss.as.jaxrs"/>

                      <extension module="org.jboss.as.jdr"/>

                      <extension module="org.jboss.as.jmx"/>

                      <extension module="org.jboss.as.jpa"/>

                      <extension module="org.jboss.as.jsf"/>

                      <extension module="org.jboss.as.logging"/>

                      <extension module="org.jboss.as.mail"/>

                      <extension module="org.jboss.as.naming"/>

                      <extension module="org.jboss.as.pojo"/>

                      <extension module="org.jboss.as.remoting"/>

                      <extension module="org.jboss.as.sar"/>

                      <extension module="org.jboss.as.security"/>

                      <extension module="org.jboss.as.threads"/>

                      <extension module="org.jboss.as.transactions"/>

                      <extension module="org.jboss.as.webservices"/>

                      <extension module="org.jboss.as.weld"/>

                      <extension module="org.wildfly.extension.batch"/>

                      <extension module="org.wildfly.extension.io"/>

                      <extension module="org.wildfly.extension.undertow"/>

                  </extensions>

               

               

                  <management>

                      <security-realms>

                          <security-realm name="ManagementRealm">

                              <authentication>

                                  <local default-user="$local"/>

                                  <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>

                              </authentication>

                              <authorization map-groups-to-roles="false">

                                  <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>

                              </authorization>

                          </security-realm>

                          <security-realm name="ApplicationRealm">

                              <authentication>

                                  <local default-user="$local" allowed-users="*"/>

                                  <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>

                              </authentication>

                              <authorization>

                                  <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>

                              </authorization>

                          </security-realm>

                      </security-realms>

                      <audit-log>

                          <formatters>

                              <json-formatter name="json-formatter"/>

                          </formatters>

                          <handlers>

                              <file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>

                          </handlers>

                          <logger log-boot="true" log-read-only="false" enabled="false">

                              <handlers>

                                  <handler name="file"/>

                              </handlers>

                          </logger>

                      </audit-log>

                      <management-interfaces>

                          <http-interface security-realm="ManagementRealm" http-upgrade-enabled="true">

                              <socket-binding http="management-http"/>

                          </http-interface>

                      </management-interfaces>

                      <access-control provider="simple">

                          <role-mapping>

                              <role name="SuperUser">

                                  <include>

                                      <user name="$local"/>

                                  </include>

                              </role>

                          </role-mapping>

                      </access-control>

                  </management>

               

                  <profile>

                      <subsystem xmlns="urn:jboss:domain:logging:2.0">

                          <console-handler name="CONSOLE">

                              <level name="INFO"/>

                              <formatter>

                                  <named-formatter name="COLOR-PATTERN"/>

                              </formatter>

                          </console-handler>

                          <periodic-rotating-file-handler name="FILE" autoflush="true">

                              <formatter>

                                  <named-formatter name="PATTERN"/>

                              </formatter>

                              <file relative-to="jboss.server.log.dir" path="server.log"/>

                              <suffix value=".yyyy-MM-dd"/>

                              <append value="true"/>

                          </periodic-rotating-file-handler>

                          <logger category="com.arjuna">

                              <level name="WARN"/>

                          </logger>

                          <logger category="org.apache.tomcat.util.modeler">

                              <level name="WARN"/>

                          </logger>

                          <logger category="org.jboss.as.config">

                              <level name="DEBUG"/>

                          </logger>

                          <logger category="sun.rmi">

                              <level name="WARN"/>

                          </logger>

                          <logger category="jacorb">

                              <level name="WARN"/>

                          </logger>

                          <logger category="jacorb.config">

                              <level name="ERROR"/>

                          </logger>

                          <logger category="org.jboss.security">

                              <level name="TRACE"/>

                          </logger>

                          <root-logger>

                              <level name="INFO"/>

                              <handlers>

                                  <handler name="CONSOLE"/>

                                  <handler name="FILE"/>

                              </handlers>

                          </root-logger>

                          <formatter name="PATTERN">

                              <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>

                          </formatter>

                          <formatter name="COLOR-PATTERN">

                              <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>

                          </formatter>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:batch:1.0">

                          <job-repository>

                              <in-memory/>

                          </job-repository>

                          <thread-pool>

                              <max-threads count="10"/>

                              <keepalive-time time="100" unit="milliseconds"/>

                          </thread-pool>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:datasources:2.0">

                          <datasources>

                              <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">

                                  <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>

                                  <driver>h2</driver>

                                  <security>

                                      <user-name>sa</user-name>

                                      <password>sa</password>

                                  </security>

                              </datasource>

                              <datasource jta="true" jndi-name="java:/jdbc/hq" pool-name="postgresDS" enabled="true" use-java-context="true" use-ccm="true">

                                  <connection-url>jdbc:postgresql://127.0.0.1:5432/hq</connection-url>

                                  <driver-class>org.postgresql.Driver</driver-class>

                                  <driver>postgresql</driver>

                                  <pool>

                                      <min-pool-size>2</min-pool-size>

                                      <max-pool-size>20</max-pool-size>

                                  </pool>

                                  <security>

                                      <user-name>hq</user-name>

                                      <password>hq</password>

                                  </security>

                                  <validation>

                                      <validate-on-match>false</validate-on-match>

                                      <background-validation>false</background-validation>

                                      <background-validation-millis>1</background-validation-millis>

                                  </validation>

                                  <statement>

                                      <prepared-statement-cache-size>0</prepared-statement-cache-size>

                                      <share-prepared-statements>false</share-prepared-statements>

                                  </statement>

                              </datasource>

                              <drivers>

                                  <driver name="postgresql" module="org.postgresql">

                                      <xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>

                                  </driver>

                                  <driver name="h2" module="com.h2database.h2">

                                      <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>

                                  </driver>

                              </drivers>

                          </datasources>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">

                          <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000"/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:ee:2.0">

                          <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>

                          <jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement>

                          <annotation-property-replacement>false</annotation-property-replacement>

                          <concurrent>

                              <context-services>

                                  <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>

                              </context-services>

                              <managed-thread-factories>

                                  <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>

                              </managed-thread-factories>

                              <managed-executor-services>

                                  <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" core-threads="5" max-threads="25" keepalive-time="5000"/>

                              </managed-executor-services>

                              <managed-scheduled-executor-services>

                                  <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" core-threads="2" keepalive-time="3000"/>

                              </managed-scheduled-executor-services>

                          </concurrent>

                          <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" jms-connection-factory="java:jboss/DefaultJMSConnectionFactory" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:ejb3:2.0">

                          <session-bean>

                              <stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>

                              <singleton default-access-timeout="5000"/>

                          </session-bean>

                          <pools>

                              <bean-instance-pools>

                                  <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>

                                  <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>

                              </bean-instance-pools>

                          </pools>

                          <caches>

                              <cache name="simple"/>

                              <cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>

                          </caches>

                          <passivation-stores>

                              <passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>

                          </passivation-stores>

                          <async thread-pool-name="default"/>

                          <timer-service thread-pool-name="default" default-data-store="default-file-store">

                              <data-stores>

                                  <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>

                              </data-stores>

                          </timer-service>

                          <remote connector-ref="http-remoting-connector" thread-pool-name="default"/>

                          <thread-pools>

                              <thread-pool name="default">

                                  <max-threads count="10"/>

                                  <keepalive-time time="100" unit="milliseconds"/>

                              </thread-pool>

                          </thread-pools>

                          <default-security-domain value="hq"/>

                          <default-missing-method-permissions-deny-access value="true"/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:io:1.1">

                          <worker name="default" io-threads="8" task-max-threads="64"/>

                          <buffer-pool name="default"/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:infinispan:2.0">

                          <cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">

                              <local-cache name="passivation" batching="true">

                                  <file-store passivation="true" purge="false"/>

                              </local-cache>

                              <local-cache name="persistent" batching="true">

                                  <file-store passivation="false" purge="false"/>

                              </local-cache>

                          </cache-container>

                          <cache-container name="ejb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan" aliases="sfsb">

                              <local-cache name="passivation" batching="true">

                                  <file-store passivation="true" purge="false"/>

                              </local-cache>

                              <local-cache name="persistent" batching="true">

                                  <file-store passivation="false" purge="false"/>

                              </local-cache>

                          </cache-container>

                          <cache-container name="hibernate" default-cache="local-query" module="org.hibernate">

                              <local-cache name="entity">

                                  <transaction mode="NON_XA"/>

                                  <eviction strategy="LRU" max-entries="10000"/>

                                  <expiration max-idle="100000"/>

                              </local-cache>

                              <local-cache name="local-query">

                                  <transaction mode="NONE"/>

                                  <eviction strategy="LRU" max-entries="10000"/>

                                  <expiration max-idle="100000"/>

                              </local-cache>

                              <local-cache name="timestamps">

                                  <transaction mode="NONE"/>

                                  <eviction strategy="NONE"/>

                              </local-cache>

                          </cache-container>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>

                      <subsystem xmlns="urn:jboss:domain:jca:2.0">

                          <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>

                          <bean-validation enabled="true"/>

                          <default-workmanager>

                              <short-running-threads>

                                  <core-threads count="50"/>

                                  <queue-length count="50"/>

                                  <max-threads count="50"/>

                                  <keepalive-time time="10" unit="seconds"/>

                              </short-running-threads>

                              <long-running-threads>

                                  <core-threads count="50"/>

                                  <queue-length count="50"/>

                                  <max-threads count="50"/>

                                  <keepalive-time time="10" unit="seconds"/>

                              </long-running-threads>

                          </default-workmanager>

                          <cached-connection-manager/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:jdr:1.0"/>

                      <subsystem xmlns="urn:jboss:domain:jmx:1.3">

                          <expose-resolved-model/>

                          <expose-expression-model/>

                          <remoting-connector/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:jpa:1.1">

                          <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:jsf:1.0"/>

                      <subsystem xmlns="urn:jboss:domain:mail:2.0">

                          <mail-session name="default" jndi-name="java:jboss/mail/Default">

                              <smtp-server outbound-socket-binding-ref="mail-smtp"/>

                          </mail-session>

                          <mail-session name="hqMail" jndi-name="java:/hqMail">

                              <smtp-server outbound-socket-binding-ref="mail-smtp-gmail" ssl="true" username="hq@gmail.com" password="to be registered out"/>

                          </mail-session>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:naming:2.0">

                          <remote-naming/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:pojo:1.0"/>

                      <subsystem xmlns="urn:jboss:domain:remoting:2.0">

                          <endpoint worker="default"/>

                          <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:resource-adapters:2.0"/>

                      <subsystem xmlns="urn:jboss:domain:sar:1.0"/>

                      <subsystem xmlns="urn:jboss:domain:security:1.2">

                          <security-domains>

                              <security-domain name="dice">

                                  <authentication>

                                      <login-module code="Database" flag="required">

                                          <module-option name="dsJndiName" value="java:/jdbc/dice"/>

                                          <module-option name="principalsQuery" value="select passwordHash from player where lower(playertag)= lower(?)"/>

                                          <module-option name="rolesQuery" value="select role, 'Roles' from playerrole pr join player p on (pr.player_id = p.id) where lower(p.playertag)= lower(?)"/>

                                          <module-option name="unauthenticatedIdentity" value="guest"/>

                                          <module-option name="hashAlgorithm" value="SHA-256"/>

                                          <module-option name="hashEncoding" value="base64"/>

                                      </login-module>

                                  </authentication>

                              </security-domain>

                              <security-domain name="hq">

                                  <authentication>

                                      <login-module code="Database" flag="required">

                                          <module-option name="dsJndiName" value="java:/jdbc/hq"/>

                                          <module-option name="principalsQuery" value="select passwordHash from player where playertag= ?"/>

                                          <module-option name="rolesQuery" value="select role, 'Roles' from playerrole where player_playertag= ?"/>

                                          <module-option name="unauthenticatedIdentity" value="guest"/>

                                          <module-option name="hashAlgorithm" value="SHA-256"/>

                                          <module-option name="hashEncoding" value="base64"/>

                                      </login-module>

                                  </authentication>

                              </security-domain>

                              <security-domain name="other" cache-type="default">

                                  <authentication>

                                      <login-module code="Remoting" flag="optional">

                                          <module-option name="password-stacking" value="useFirstPass"/>

                                      </login-module>

                                      <login-module code="RealmDirect" flag="required">

                                          <module-option name="password-stacking" value="useFirstPass"/>

                                      </login-module>

                                  </authentication>

                              </security-domain>

                              <security-domain name="jboss-web-policy" cache-type="default">

                                  <authorization>

                                      <policy-module code="Delegating" flag="required"/>

                                  </authorization>

                              </security-domain>

                              <security-domain name="jboss-ejb-policy" cache-type="default">

                                  <authorization>

                                      <policy-module code="Delegating" flag="required"/>

                                  </authorization>

                              </security-domain>

                          </security-domains>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:threads:1.1"/>

                      <subsystem xmlns="urn:jboss:domain:transactions:2.0">

                          <core-environment>

                              <process-id>

                                  <uuid/>

                              </process-id>

                          </core-environment>

                          <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>

                          <coordinator-environment default-timeout="300"/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:undertow:1.1">

                          <buffer-cache name="default"/>

                          <server name="default-server">

                              <http-listener name="default" socket-binding="http"/>

                              <host name="default-host" alias="localhost">

                                  <location name="/" handler="welcome-content"/>

                                  <filter-ref name="server-header"/>

                                  <filter-ref name="x-powered-by-header"/>

                              </host>

                          </server>

                          <servlet-container name="default">

                              <jsp-config/>

                          </servlet-container>

                          <handlers>

                              <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>

                          </handlers>

                          <filters>

                              <response-header name="server-header" header-name="Server" header-value="Wildfly 8"/>

                              <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow 1"/>

                          </filters>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:webservices:1.2">

                          <modify-wsdl-address>true</modify-wsdl-address>

                          <wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>

                          <endpoint-config name="Standard-Endpoint-Config"/>

                          <endpoint-config name="Recording-Endpoint-Config">

                              <pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">

                                  <handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>

                              </pre-handler-chain>

                          </endpoint-config>

                          <client-config name="Standard-Client-Config"/>

                      </subsystem>

                      <subsystem xmlns="urn:jboss:domain:weld:2.0"/>

                  </profile>

               

                  <interfaces>

                      <interface name="management">

                          <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>

                      </interface>

                      <interface name="public">

                          <inet-address value="${jboss.bind.address:127.0.0.1}"/>

                      </interface>

                      <interface name="unsecure">

                          <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/>

                      </interface>

                  </interfaces>

               

                  <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">

                      <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>

                      <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>

                      <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>

                      <socket-binding name="http" port="${jboss.http.port:8080}"/>

                      <socket-binding name="https" port="${jboss.https.port:8443}"/>

                      <socket-binding name="txn-recovery-environment" port="4712"/>

                      <socket-binding name="txn-status-manager" port="4713"/>

                      <outbound-socket-binding name="mail-smtp">

                          <remote-destination host="localhost" port="25"/>

                      </outbound-socket-binding>

                      <outbound-socket-binding name="mail-smtp-gmail">

                          <remote-destination host="smtp.gmail.com" port="465"/>

                      </outbound-socket-binding>

                  </socket-binding-group>

               

              </server>

               

              The Realm hq is my default security realm. Should be sufficient?

              best regards,

              m

              • 4. Re: Websocket Auth
                auth.gabor

                Hi,

                 

                I try to use WebSocket with authentication, but I've stuck around the injection, the WildFly (both 8.0.0 and 8.1.0) didn't inject any EJB into the WebSocket endpoint. I've tried lot of combination, but only one worked: the @Inject on the interface of the EJB and the @Named on the WebSocket endpoint class... but the security propagation is not worked, I've always get "anonymous" from the context but the session.getUserPrincipal() returns with right value.

                 

                Bye,

                Gábor Auth