Issue Details (XML | Word | Printable)

Key: GDS-592
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: William Draï
Reporter: Stefaan Nachtergaele
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
GraniteDS

Spring: when user nog logged, identity.isLoggedIn call neither result nor fault handler

Created: 18/Dec/09 10:33 AM   Updated: 28/Dec/09 07:51 PM   Resolved: 28/Dec/09 07:51 PM
Component/s: Security, Spring services
Affects Version/s: 2.1.0_RC1
Fix Version/s: 2.1.0_RC2

Environment:
windows, java 1.6.0_17, tomcat 5.
ried this with granite 2.1.0_RC1 and the nightly: GDS-CORE-375


 Description  « Hide
identity.isLoggedIn(isLoggedInTrue, isLoggedInFalse);
when user is logged in, isLoggedInTrue get called. However, when he's not logged in neither get's called.
Test case:
<code>
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                preinitialize="Spring.getInstance().initApplication()"
                creationComplete="init()">


    <mx:Script>
    <![CDATA[
        import mx.logging.Log;
        import mx.logging.LogEventLevel;
        import mx.logging.targets.TraceTarget;

        import org.granite.tide.events.TideFaultEvent;
        import org.granite.tide.events.TideResultEvent;
        import org.granite.tide.spring.Identity;
        import org.granite.tide.spring.Spring;

        [Bindable]
        [In]
        public var identity:Identity;

        public function init():void {
            trace("call identity.isLoggedIn(isLoggedInTrue);");
            var t:TraceTarget = new TraceTarget();
            t.includeCategory = true;
            t.includeLevel = true;
            t.filters = ["*"];
            t.includeTime = true;
            t.level = LogEventLevel.DEBUG;
            Log.addTarget(t);
            identity.isLoggedIn(isLoggedInTrue, isLoggedInFalse);
        }


        public function isLoggedInTrue(event:TideResultEvent):void {
            trace("isLoggedInTrue;");
            this.success.enabled = true;
        }

        public function isLoggedInFalse(event:TideFaultEvent):void {
            trace("isLoggedInFalse;")
            this.failure.enabled = true;
        }

    ]]>
  </mx:Script>
    <mx:VBox>
        <mx:Label text="simple login test: {identity.loggedIn}" fontSize="24"/>
        <mx:Label id="success" text="success" enabled="false" fontSize="24"/>
        <mx:Label id="failure" text="failure" enabled="false" fontSize="24"/>
    </mx:VBox>
</mx:Application>


<code>


Stefaan Nachtergaele added a comment - 22/Dec/09 11:35 AM
I've looked through the code and I've found that the user defined fault handler simply never gets called. I've worked around this in the following way:

          var spring:Spring = Spring.getInstance();
          var tideResponder:TideResponder = new TideResponder(isLoggedInTrue, dontMatterCauseIDontGetCalled);
          spring.invokeComponent(spring.getContext(), identity, "isLoggedIn", [], tideResponder, true, null, spring.isLoggedInSuccessHandler, thisFailHandlerDoesGetCalled);

with:
    public function isLoggedInTrue(event:TideResultEvent):void {
            ....
        }

        public function dontMatterCauseIDontGetCalled(event:TideFaultEvent):void {
            .....
        }

        public function thisFailHandlerDoesGetCalled(sourceContext:BaseContext, sourceModulePrefix:String,
                                                     data:Object, componentName:String = null, op:String = null,
                                                     tideResponder:ITideResponder = null):void {
           ....
        }

William Draï added a comment - 22/Dec/09 06:35 PM
Can you post your configuration (services-config.xml, web.xml and granite-config.xml) because I can't reproduce the problem.

Stefaan Nachtergaele added a comment - 22/Dec/09 07:17 PM
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_2_5.xsd"
         version="2.5">

    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:SpringConfigurator.xml
            classpath:hibernate.cfg.xml
            classpath:applicationContext-web.xml
            classpath:applicationContext-data-source.xml
            classpath:applicationContext-common-business.xml
            classpath:applicationContext-seed.xml
        </param-value>
    </context-param>
    <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>
            5000
        </param-value>
    </context-param>
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>
            classpath:log4j.properties
        </param-value>
    </context-param>


    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/mvc/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>hibernate</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>flushMode</param-name>
            <param-value>AUTO</param-value>
        </init-param>
        <init-param>
            <param-name>sessionFactoryBeanName</param-name>
            <param-value>cacheSessionFactory</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>hibernate</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--<servlet>-->
    <!--<servlet-name>visual-reach</servlet-name>-->
    <!--<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>-->
    <!--<load-on-startup>1</load-on-startup>-->
    <!--</servlet>-->
    <!--<servlet-mapping>-->
    <!--<servlet-name>visual-reach</servlet-name>-->
    <!--<url-pattern>/system/*</url-pattern>-->
    <!--</servlet-mapping>-->
    <!--<servlet>-->
    <!--<servlet-name>LoadFileServlet</servlet-name>-->
    <!--<servlet-class>upload.LoadFileServlet</servlet-class>-->

    <!--</servlet>-->
    <!--<servlet-mapping>-->
    <!--<servlet-name>LoadFileServlet</servlet-name>-->
    <!--<url-pattern>/LoadFileServlet</url-pattern>-->
    <!--</servlet-mapping>-->
    <!--<servlet>-->
    <!--<servlet-name>TestServlet</servlet-name>-->
    <!--<servlet-class>com.visualreach.util.CacheTestServlet</servlet-class>-->
    <!--</servlet>-->
    <!--<servlet-mapping>-->
    <!--<servlet-name>TestServlet</servlet-name>-->
    <!--<url-pattern>/TestServlet/*</url-pattern>-->
    <!--</servlet-mapping>-->

    <display-name>Web Shop NAME</display-name>
    <description>Web shop application</description>

    <!-- Granite config context listener -->
    <listener>
        <listener-class>org.granite.config.GraniteConfigListener</listener-class>
    </listener>

    <!--Uncomment (part of) this block if configs are not present at default locations.-->
    <context-param>
        <param-name>servicesConfigPath</param-name>
        <param-value>/WEB-INF/flex/services-config.xml</param-value>
    </context-param>
    <context-param>
        <param-name>graniteConfigPath</param-name>
        <param-value>/WEB-INF/granite/granite-config.xml</param-value>
    </context-param>

    <filter>
        <filter-name>AMFMessageFilter</filter-name>
        <filter-class>org.granite.messaging.webapp.AMFMessageFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AMFMessageFilter</filter-name>
        <url-pattern>/graniteamf/*</url-pattern>
    </filter-mapping>


    <servlet>
        <servlet-name>AMFMessageServlet</servlet-name>
        <servlet-class>org.granite.messaging.webapp.AMFMessageServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>AMFMessageServlet</servlet-name>
        <url-pattern>/graniteamf/*</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>ImageUploadHandler</servlet-name>
        <servlet-class>org.unctv.fileupload.ImageUploadHandler</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ImageUploadHandler</servlet-name>
        <url-pattern>/uploadhandler</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>0</session-timeout>
    </session-config>


    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    <mime-mapping>
        <extension>html</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>txt</extension>
        <mime-type>text/plain</mime-type>
    </mime-mapping>


    <!--<error-page>-->
    <!--<error-code>500</error-code>-->
    <!--<location>/jsp/error.jsp</location>-->
    <!--</error-page>-->
    <!--<error-page>-->
    <!--<error-code>400</error-code>-->
    <!--<location>/jsp/index.jsp</location>-->
    <!--</error-page>-->

</web-app>

services-config.xml
<services-config>

    <!--
     ! Declares Flex services. This configuration uses automated destinations
     ! discovery: see test.granite.ejb3.service.PersonServiceBean.java (the
     ! @RemoteDestination(id="person", securityRoles={"user","admin"}) annotation)
     ! and granite-config.xml (the scan="true" attribute). There is no need to
     ! set the factory: since only one factory is configured, it will be used by
     ! default.
     !
     ! See also Persons.mxml for the RemoteObject configuration.
     !-->
    <services>
        <service id="granite-service"
            class="flex.messaging.services.RemotingService"
            messageTypes="flex.messaging.messages.RemotingMessage">
            <!--
             ! Use "tideSeamFactory" and "my-graniteamf" for "ejb" destination (see below).
             !-->
            <destination id="spring">
                <channels>
                    <channel ref="my-graniteamf"/>
                </channels>
                <properties>
                    <factory>tideSpringFactory</factory>
                    <persistence-manager-bean-name>tidePersistenceManager</persistence-manager-bean-name>
                </properties>
                <security>
                    <security-constraint>
                        <auth-method>Custom</auth-method>
                        <roles>
                            <role>ROLE_USER</role>
                            <role>ROLE_ADMIN</role>
                        </roles>
                    </security-constraint>
                </security>
                
            </destination>
        </service>

        <service id="gravity-service"
            class="flex.messaging.services.MessagingService"
            messageTypes="flex.messaging.messages.AsyncMessage">
            <adapters>
                <!--adapter-definition id="jms" class="org.granite.gravity.adapters.JMSServiceAdapter"/-->
                <adapter-definition id="simple" class="org.granite.gravity.adapters.SimpleServiceAdapter"/>
            </adapters>

            <destination id="lotTopic">
                <properties>
                  <!--jms>
                    <destination-type>Topic</destination-type>
                    <connection-factory>ConnectionFactory</connection-factory>
                    <destination-jndi-name>topic/testTopic</destination-jndi-name>
                    <destination-name>dataTopic</destination-name>
                    <acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
                    <transacted-sessions>true</transacted-sessions>
                    <no-local>true</no-local>
                  </jms-->
                  <no-local>true</no-local>
                  <session-selector>true</session-selector>
                </properties>
                <channels>
                    <channel ref="my-gravityamf"/>
                </channels>
                <adapter ref="simple"/>
            </destination>
        </service>

        <service id="brand-service"
                   class="flex.messaging.services.RemotingService"
                   messageTypes="flex.messaging.messages.RemotingMessage">
                   <destination id="pojo">
                       <channels>
                           <channel ref="my-graniteamf"/>
                       </channels>
                       <properties>
                           <scope>session</scope>
                           <source>test.pojo.PojoService</source>
                       </properties>
                   </destination>
               </service>

    </services>

    <!--
     ! Declares ejbFactory service factory.
     !-->
    <factories>
        <factory id="tideSpringFactory" class="org.granite.tide.spring.SpringServiceFactory">
        </factory>
    </factories>

    <!--
     ! Declares my-graniteamf channel.
     !-->
    <channels>
        <channel-definition id="my-graniteamf" class="mx.messaging.channels.AMFChannel">
            <endpoint
                uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf"
                class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>

        <channel-definition id="my-gravityamf" class="org.granite.gravity.channels.GravityChannel">
            <endpoint
                uri="http://{server.name}:{server.port}/{context.root}/gravity/amf"
                class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>
</services-config>

<granite-config scan="true">

<security type="org.granite.messaging.service.security.SpringSecurityService"/>

    <!--
     ! Enable all Spring Service components for Tide
     !-->
    <!--<classgetter type="org.granite.hibernate.HibernateClassGetter"/>-->
    
    <tide-components >
     <tide-component instance-of="org.granite.tide.spring.security.Identity"/>
        <tide-component annotated-with="org.springframework.stereotype.Service" />
        <tide-component annotated-with="org.springframework.stereotype.Controller"/>
    </tide-components>

</granite-config>

William Draï added a comment - 28/Dec/09 05:21 PM
This does not work because the 'spring' destination is secured in services-config.xml.
A workaround for now is to remove security on the spring destination, authorization should be made at Spring bean level anyway.