Announcement Announcement Module
Collapse
No announcement yet.
Extracting UserDetails in Flex client Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Extracting UserDetails in Flex client

    Hi there:

    I have a Flex project that is successfully authenticating users using spring-security via spring-blazeds integration. For completeness sake, my backend is configured as follows:

    spring-flex.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
    	<import resource="classpath:core/main-context.xml" />	
    
    	<flex:message-broker>
    		<flex:secured />
    	</flex:message-broker>
    	
    	<bean id="userService" class="com.mymodules.security.service.spring.UserServiceImpl">
    		<constructor-arg ref="userDao" />
    		<flex:remote-service />
    	</bean>
    </beans>
    spring-security.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
    	<http auto-config="true" session-fixation-protection="none"/>
    
    	<authentication-provider user-service-ref='userService'/>
     
    </beans>
    The above “userService” bean is an instance of my custom class, UserServiceImpl, which implements the interface org.springframework.security.userdetails.UserDetai lsService:
    Code:
        UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException;
    As most of you probably know, UserDetails contains the various roles associated with a user: these can be retrieved via the UserDetails.getAuthorities() method.

    For blazeDs configuration I have:

    WEB-INF/flex/services-config.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <services-config>
    
    	<services>
    		<default-channels>
    			<channel ref="my-amf" />
    		</default-channels>
    	</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" />
    			<properties>
    				<polling-enabled>false</polling-enabled>
    			</properties>
    		</channel-definition>
    	</channels>
    
    </services-config>
    Now, on the front-end, I have an ActionScript UserDelagate.as class which performs login/logout via a ChannelSet; the relavant snippet:
    Code:
    		public function UserDelegate( channelSet:ChannelSet )
    		{
    			this.service = channelSet;
    			this.service.addEventListener( ResultEvent.RESULT, onSuccess );
    			this.service.addEventListener( FaultEvent.FAULT, onFailure );	
    		}
    
    		
    		public function login( username:String, password:String ):void {
    		
    			service.login( username, password );
    			
    		}
    		
    		public function logout():void {
    		
    			service.logout();
    		}
    Finally, on the clien-side, I inject the ChannelSet into the UserDelegate via spring-actionscript:

    spring-client.xml
    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <objects>
    
    	<property file="properties.config" />
    
    
    	<!-- Remote Services -->
    	
    	<object id="channelSet" class="mx.messaging.ChannelSet">
    		<method-invocation name="addChannel">
    			<arg>
    				<object id="amfChannel" class="mx.messaging.channels.AMFChannel">
    					<property name="url"
    						value="http://${host}:${port}/${context-root}/messagebroker/amf" />
    				</object>
    			</arg>
    		</method-invocation>
    	</object>
    	
    	<!-- Business Delegates -->
    	
    	<object id="delegateLocator" class="hc.control.delegates.DelegateLocator" factory-method="getInstance" >
    		<property name="userDelegate">
    			<object class="hc.control.delegates.UserDelegate" >
    				<constructor-arg ref="channelSet"/>
    			</object>
    		</property>
    	</object>
    
    </objects>
    This is all presently working. Now, what I'd like to do is to extract the user roles from the UserDetails object resulting from the invocation of the UserService.loadUserByUsername method on the backend (which gets triggered by the UserDelegate.login method in the flex client). Can this be done in a single call? I'd like to avoid having to perform two distinct invocations (one for login and one for userService) every time the user logs in.

    Any help or ideas is greatly appreciated.

    Thanks in advanced.

  • #2
    Hmmm...this is somewhat a limitation of the BlazeDS AuthenticationService in that it just returns a "success" message on successful login, and that's what gets encoded into the "result" property of the ResultEvent on the client side.

    That said, we are already intercepting the message dispatch using AOP, so we could perhaps inject some more useful information into the result. Do you think making the GrantedAuthority[] from UserDetails available in the ResultEvent would be sufficient? If we implement this, we would probably make it a feature that you have to explicitly turn on with a flag in the <flex:secured> tag.

    Comment


    • #3
      Originally posted by jeremyg484 View Post
      That said, we are already intercepting the message dispatch using AOP, so we could perhaps inject some more useful information into the result. Do you think making the GrantedAuthority[] from UserDetails available in the ResultEvent would be sufficient? If we implement this, we would probably make it a feature that you have to explicitly turn on with a flag in the <flex:secured> tag.
      This would be perfect. Having the user roles (ie GrantedAuthority[]) available in the ResultEvent would allow the flex client to determine the target transition state from the login screen: a regular user would be presented with a different set of screens than an admin user.

      Let me know if this doable and how can I be notified once this feature is added.

      Thanks in advanced

      Comment


      • #4
        Great, i also need this feature

        In order to be notified, watch the FLEX-35 Jira issue

        Comment


        • #5
          Spring authentication using database

          Hi Jeremy ,
          I just wanted to know how to do database authentication using flex-blazeds-spring security. I'm trying to use UserDetailsService implmented by my custom class.I have one User domain class which implements Userdetails interface.
          When I'm trying to run the application I get "Null pointer exception". It's failing to find the AuthenticationManager refernce.
          AuthenticationManager manager = (AuthenticationManager)appContext.getBean("_authen ticationManager");
          manager is null here ,I'm not sure where exactly this "_authenticationManager" is mapped .
          I'm using same code base but using database authentication instead of In memory authentication done in "AuthenticationHelper.java" class
          Help with java class and config file samples will be greatly appreciated. Error which i'm getting is mentioned below.
          Thanks,
          Anand
          -------------------------------------------------------------------------------------
          23:39:44,359 DEBUG FilterChainProxy:355 - /messagebroker/amf reached end of addi
          tional filter chain; proceeding with original chain
          [BlazeDS]Channel endpoint my-amf received request.
          [BlazeDS]Deserializing AMF/HTTP request
          Version: 3
          (Message #0 targetURI=null, responseURI=/2)
          (Array #0)
          [0] = (Typed Object #0 'flex.messaging.messages.RemotingMessage')
          source = null
          operation = "authenticatePrincipal"
          body = (Array #1)
          [0] = "9999"
          [1] = "555DP"
          messageId = "517742BA-F99B-F173-4856-C766CBED8B2F"
          clientId = null
          timeToLive = 0
          timestamp = 0
          headers = (Object #2)
          DSId = "6D1F9A62-809A-B6A5-1300-06878BE44FEA"
          DSEndpoint = "my-amf"
          destination = "authenticationHelper"

          23:39:44,375 DEBUG DefaultListableBeanFactory:214 - Returning cached instance of
          singleton bean '_authenticationManager'
          23:39:44,375 DEBUG ProviderManager:190 - Authentication attempt using org.spring
          framework.security.providers.dao.DaoAuthentication Provider
          23:39:44,390 DEBUG SharedEntityManagerCreator$SharedEntityManagerInvo cationHandl
          er:185 - Creating new EntityManager for shared EntityManager invocation
          23:39:44,484 DEBUG EntityManagerFactoryUtils:311 - Closing JPA EntityManager
          [BlazeDS]Serializing AMF/HTTP response
          Version: 3
          (Message #0 targetURI=/2/onStatus, responseURI=)
          (Typed Object #0 'flex.messaging.messages.ErrorMessage')
          headers = (Object #1)
          rootCause = (Typed Object #2 'java.lang.NullPointerException')
          message = null
          localizedMessage = null
          cause = null
          body = null
          correlationId = "517742BA-F99B-F173-4856-C766CBED8B2F"
          faultDetail = null
          faultString = "java.lang.NullPointerException : null"
          clientId = "6D1FA670-70E6-337C-5252-96562BAD4F36"
          timeToLive = 0.0
          destination = "authenticationHelper"
          timestamp = 1.2402959845E12
          extendedData = null
          faultCode = "Server.Processing"
          messageId = "6D1FB983-4086-745D-C4E1-2FBD2919B59B"

          23:39:44,500 DEBUG ExceptionTranslationFilter:104 - Chain processed normally
          --------------------------------------------------------------------------------------
          Last edited by anandintouch; Apr 21st, 2009, 01:43 AM.

          Comment


          • #6
            Originally posted by anandintouch View Post
            I just wanted to know how to do database authentication using flex-blazeds-spring security.
            So from your posted log, it looks like you are trying to call your authentication logic directly via RPC. Why not use ChannelSet.login()? If you have Spring Security configured properly, your custom user details service should get called.

            Comment

            Working...
            X