4 Replies Latest reply on Apr 18, 2010 7:01 PM by agungdmt

    how to implement springsecurity in flex

    agungdmt Level 1

      Hi..All

      i'm newbie and need your help

       

      I have  difficulty in the implementation of security on the flex project using  spring security. in implementation the project i'm using

      • BlazeDS Turnkey.
      • Apache Tomcat
      • Eclipse Ganymede 3.4 (for editing code)


      I've tried to make it but always get an error message

      "[MessagingError  message = 'Destination' securityHelper 'either does not exist or the  destination has no channels defined (and the application does not define  any default channels .)']- could not establish a connection to'  securityHelper'-InvokeFailed"

      and below my source  code

       

      1. web.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app id="WebApp_ID" version="2.4"
        xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

       

          <display-name>Spring BlazeDS Integration Samples</display-name>

       

          <context-param>
              <param-name>flex.class.path</param-name>
              <param-value>/WEB-INF/flex/hotfixes,/WEB-INF/flex/jars</param-value>
          </context-param>

       

          <context-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>
                  /WEB-INF/spring/*-config.xml
              </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>
         
          <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
          
          <!-- Http Flex Session attribute and binding listener support -->
          <listener>
              <listener-class>flex.messaging.HttpFlexSession</listener-class>
          </listener>
         
         
          <!-- MessageBroker Servlet
          <servlet>
              <servlet-name>MessageBrokerServlet</servlet-name>
              <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
              <init-param>
                  <param-name>services.configuration.file</param-name>
                  <param-value>/WEB-INF/flex/services-config.xml</param-value>
              </init-param>
              <init-param>
                  <param-name>flex.write.path</param-name>
                  <param-value>/WEB-INF/flex</param-value>
              </init-param>
              <load-on-startup>1</load-on-startup>
          </servlet>

       

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

       

          <servlet-mapping>
              <servlet-name>flex</servlet-name>
              <url-pattern>/messagebroker/*</url-pattern>
           </servlet-mapping>
          
          <welcome-file-list>
              <welcome-file>index.html</welcome-file>
              <welcome-file>index.htm</welcome-file>
              <welcome-file>index.jsp</welcome-file>
              <welcome-file>default.html</welcome-file>
              <welcome-file>default.htm</welcome-file>
              <welcome-file>default.jsp</welcome-file>
          </welcome-file-list>

       

      </web-app>

       

       

      2. flex-servlet.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:flex="http://www.springframework.org/schema/flex"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="
              http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
              http://www.springframework.org/schema/flex
              http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">

          <flex:message-broker>
              <flex:message-service
                  default-channels="my-streaming-amf,my-longpolling-amf,my-polling-amf" />
              <flex:secured />
          </flex:message-broker>

       

          <!-- Expose the productService bean for BlazeDS remoting -->
          <flex:remoting-destination ref="productService" />

       

          <!-- Expose the contactService bean for BlazeDS remoting -->
          <flex:remoting-destination ref="contactService" />

       

          <!-- Expose the securedProductService bean for BlazeDS remoting -->
          <flex:remoting-destination ref="securedProductService" />
         
          <!-- Helper for getting the currently authenticated user-->
          <bean id="securityHelper" class="org.springframework.flex.samples.secured.SecurityHelper">
              <flex:remoting-destination/>
          </bean>

       

          <!-- Messaging destinations -->
          <flex:message-destination id="chat" />
          <flex:message-destination id="secured-chat" send-security-constraint="trusted" />
          <flex:message-destination id="simple-feed" />
          <flex:message-destination id="market-feed" allow-subtopics="true" subtopic-separator="." />
          <flex:jms-message-destination id="jms-chat" jms-destination="chatTopic" />     <!-- See configuration of "chatTopic" in /WEB-INF/spring/infrastructure-config.xml -->
          <flex:integration-message-destination id="si-receive" message-channel="toFlex"/> <!-- See configuration of "toFlex" in /WEB-INF/spring/integration-config.xml -->
          <flex:integration-message-destination id="si-send" message-channel="fromFlex"/> <!-- See configuration of "fromFlex" in /WEB-INF/spring/integration-config.xml -->      

       

          <!-- MessageTemplate makes it easy to publish messages -->
          <bean id="defaultMessageTemplate" class="org.springframework.flex.messaging.MessageTemplate" />

       

          <!-- Pojo used to start and stop the data feed that pushes data in the 'simple-feed' destination -->
          <bean id="simpleFeedStarter" class="org.springframework.flex.samples.simplefeed.SimpleFeed">
              <constructor-arg ref="defaultMessageTemplate" />
              <flex:remoting-destination />
          </bean>

       

          <!-- Pojo used to start and stop the data feed that pushes data in the 'market-feed' destination -->
          <bean id="marketFeedStarter" class="org.springframework.flex.samples.marketfeed.MarketFeed">
              <constructor-arg ref="defaultMessageTemplate" />
              <constructor-arg value="stocklist.xml" />
              <flex:remoting-destination />
          </bean>

       

      </beans>

       

      3.service-config.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <services-config>

       

          <services>
              <default-channels>
                 <channel ref="my-amf"/>
              </default-channels>
              <service-include file-path="remoting-config.xml" />
              <service-include file-path="proxy-config.xml" />
              <service-include file-path="messaging-config.xml" />
          </services>

       

          <channels>

       

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

              <channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
                  <endpoint url="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
                  <properties>
                      <add-no-cache-headers>false</add-no-cache-headers>
                  </properties>
              </channel-definition>

       

              <channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">
                  <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
                  <properties>
                      <polling-enabled>true</polling-enabled>
                      <polling-interval-seconds>4</polling-interval-seconds>
                  </properties>
              </channel-definition>
             
              <channel-definition id="my-longpolling-amf" class="mx.messaging.channels.AMFChannel">
                  <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amflongpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
                  <properties>
                      <polling-enabled>true</polling-enabled>
                      <polling-interval-seconds>5</polling-interval-seconds>
                      <wait-interval-millis>60000</wait-interval-millis>
                      <client-wait-interval-millis>1</client-wait-interval-millis>
                      <max-waiting-poll-requests>200</max-waiting-poll-requests>
                  </properties>
              </channel-definition>      

       

              <channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
                  <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf" class="flex.messaging.endpoints.StreamingAMFEndpoint"/>
              </channel-definition>

       

          </channels>
         
          <security>
              <login-command class="flex.messaging.security.TomcatLoginCommand" server="Tomcat"/>
              <security-constraint id="trusted">
                  <roles>
                      <role>ROLE_USER</role>
                      <role>ROLE_ADMIN</role>
                  </roles>
              </security-constraint>
          </security>

       

          <logging>
              <target class="flex.messaging.log.ConsoleTarget" level="Warn">
                  <properties>
                      <prefix>[BlazeDS] </prefix>
                      <includeDate>false</includeDate>
                      <includeTime>false</includeTime>
                      <includeLevel>false</includeLevel>
                      <includeCategory>false</includeCategory>
                  </properties>
                  <filters>
                      <pattern>Endpoint.*</pattern>
                      <pattern>Service.*</pattern>
                      <pattern>Configuration</pattern>
                  </filters>
              </target>
          </logging>

       

          <system>
              <redeploy>
                  <enabled>false</enabled>
              </redeploy>
          </system>

       

      </services-config>

       

      4. remoting-config.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <service id="remoting-service" class="flex.messaging.services.RemotingService">
          <adapters>
              <adapter-definition id="java-object"
                  class="flex.messaging.services.remoting.adapters.JavaAdapter"
                  default="true" />
          </adapters>
          <default-channels>
              <channel ref="my-amf" />
          </default-channels>
         
      </service>

       

      5. spring/security-config.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <beans:beans xmlns="http://www.springframework.org/schema/security"
          xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                              http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
      <!--
          <http>
              <form-login default-target-url="/secured/secured.html" login-page="/login.jsp" />
          </http>
      -->
          <http>
              <form-login default-target-url="/ZeroToHero.html"/>
          </http>
         
          <authentication-provider>
              <user-service>
                  <user name="john" password="john" authorities="ROLE_USER" />
                  <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
                  <user name="guest" password="guest" authorities="ROLE_GUEST" />
              </user-service>
          </authentication-provider>

       

      </beans:beans>

       

      6. ZeroToHero.mxml

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"
          applicationComplete="applicationCompleteHandler()">

       

          <mx:RemoteObject id="productService" destination="securedProductService" fault="faultHandler(event)"/>
          <mx:RemoteObject id="securityHelperTest" destination="securityHelper" fault="faultHandler(event)">
              <mx:method name="getAuthentication" result="userHandler(event)"/>
          </mx:RemoteObject>

       

          <mx:Script>
              <![CDATA[

       

                  import mx.messaging.ChannelSet;
                  import mx.messaging.channels.AMFChannel;
                  import mx.controls.Alert;
                  import mx.rpc.AsyncToken;
                  import mx.rpc.AsyncResponder;
                  import mx.rpc.events.FaultEvent;
                  import mx.rpc.events.ResultEvent;
                 
                  [Bindable]
                  private var user:Object = null;
                 
                  private function applicationCompleteHandler():void
                  {
                      securityHelperTest.getAuthentication();
                      chat.consumer.subscribe();
                  }
                 
                  private function userHandler(event:ResultEvent):void
                  {
                      user = event.result;
                      if (user != null) {
                          userId.text = user.name;
                          userId.editable = false;
                          password.editable = false;
                      }
                  }

       

                  private function faultHandler(event:FaultEvent):void
                  {
                      Alert.show(event.fault.faultString + "-" +
                      event.fault.faultDetail + "-" +
                      event.fault.faultCode, "Error accessing RemoteObject");
                  }
                 
                  private function login():void
                  {
                      var token:AsyncToken = securityHelperTest.channelSet.login(userId.text, password.text);
                        token.addResponder(
                            new AsyncResponder(
                                function(event:ResultEvent, token:Object = null):void{
                                    user = event.result;
                                    userId.editable = false;
                                    password.editable = false;
                                },
                                function(event:FaultEvent, token:Object = null):void{
                                    Alert.show(event.fault.faultString, "Login Failed");
                                }
                            )
                        );
                  }

       

                  private function logout():void
                  {
                      securityHelperTest.channelSet.logout();
                      user = null;
                      userId.text = "";
                      userId.editable = true;
                      password.text = "";
                      password.editable = true;
                      grid.dataProvider.removeAll();       
                  }
                 
              ]]>
          </mx:Script>

       

       

       

          <mx:Form>
              <mx:FormItem label="User Id">
                  <mx:TextInput id="userId"/>
              </mx:FormItem>
              <mx:FormItem label="Password">
                  <mx:TextInput id="password" displayAsPassword="true"/>
              </mx:FormItem>
              <mx:FormItem direction="horizontal">
                  <mx:Button label="Login" click="login()"/>
                  <mx:Button label="Logout" click="logout()"/>
              </mx:FormItem>
          </mx:Form>
         
          <mx:Accordion width="100%" visible="{user != null}">
         
              <mx:Canvas label="Products" width="100%">
                  <mx:Panel width="100%">
                      <mx:DataGrid id="grid" dataProvider="{productService.findAll.lastResult}" width="100%" height="100%">
                          <mx:columns>
                              <mx:DataGridColumn dataField="productId" headerText="Product ID" visible="{user != null ? user.authorities.indexOf('ROLE_ADMIN') >= 0 : false}"/>
                              <mx:DataGridColumn dataField="name" headerText="Name" />
                              <mx:DataGridColumn dataField="category" headerText="Category" />
                              <mx:DataGridColumn dataField="description" headerText="Description" />
                              <mx:DataGridColumn dataField="image" headerText="Image" />
                              <mx:DataGridColumn dataField="price" headerText="Price" />
                              <mx:DataGridColumn dataField="qty" headerText="Qty" />
                          </mx:columns>
                      </mx:DataGrid>
                      <mx:Button label="Get Data" click="productService.findAll()"/>
                  </mx:Panel>
              </mx:Canvas>
             
              <Chat id="chat" username="{user.name}"/>
             
          </mx:Accordion>
      </mx:Application>

       

      please help me,

       

        • 1. Re: how to implement springsecurity in flex
          levancho Level 3

          I dont think that will be the only thing needed but at least, you need

          securityHelper destination defined in your blaze DS configuration file,look inside remoting-config.xml

          • 2. Re: how to implement springsecurity in flex
            agungdmt Level 1

            thanks for your response....

            i've try to setting in remote-config.xml, but still same error....

             

            you have another solution

            thank's

            • 3. Re: how to implement springsecurity in flex
              levancho Level 3

              can you post what you did in your remote-config.xml ?

              how did you define yout destination?

              • 4. Re: how to implement springsecurity in flex
                agungdmt Level 1

                remote-config.xml

                 

                <?xml version="1.0" encoding="UTF-8"?>
                <service id="remoting-service" class="flex.messaging.services.RemotingService">
                    <adapters>
                        <adapter-definition id="java-object"
                            class="flex.messaging.services.remoting.adapters.JavaAdapter"
                            default="true" />
                    </adapters>
                   
                    <default-channels>
                        <channel ref="my-amf" />
                    </default-channels>
                   
                    <destination id="securityHelper">
                        <properties>
                            <source>org.springframework.flex.samples.secured.SecurityHelper</source>
                            <scope>application</scope>
                        </properties>
                    </destination>
                 
                </service>

                 

                SecurityHelper.as (for calling remote object from client) of my own. and I think this SecurityHelper.as wrong because not return value, and I do  not know how to call a java class SecurityHelper.java

                 

                package com.adobe
                {
                    [Bindable]
                    [RemoteClass(alias="org.springframework.flex.samples.secured.SecurityHelper")]
                    public class SecurityHelper
                    {
                        public function SecurityHelper()
                        {
                        }

                 

                    }
                }

                 

                SecurityHelper.java

                 

                package org.springframework.flex.samples.secured;

                 

                import java.util.Map;

                 

                import org.springframework.flex.security.AuthenticationResultUtils;

                 

                public class SecurityHelper {

                 

                    public Map<String, Object> getAuthentication() {
                        return AuthenticationResultUtils.getAuthenticationResult();
                    }
                }

                 

                thank's

                 

                Message was edited by: agungdmt