Granite Data Services lets your Flex application connect to JBoss Seam services with full conversation and task (jBPM) support.
It also brings support for Identity security.
For a basic sample with Granite DS/Seam/Identity/Ejb3 entity beans working together, download graniteds-seam-1.0.0.zip and import it as a new Eclipse project. Please note that this sample project is a quick port of the graniteds-ejb3-1.0.0.zip and does not show any advanced conversation/task support for now.
To connect to your Seam services and maintain a conversation or task id, you need to use a specific GDS RemoteObject org.granite.seam.SeamRemoteObject and compile your mxml/as sources with the granite-seam.swc library.
Here is an overview of the SeamRemoteObject class:
public dynamic class SeamRemoteObject extends SecureRemoteObject {
...
public function get conversation():Conversation {...}
public function set conversation(conversation:Conversation):void {...}
public function get task():Task {...}
public function set task(task:Task):void {...}
...
}
Basically, Conversation and Task only encapsulate an id. Since SeamRemoteObject extends SecureRemoteObject, you may use all security features as explain here.
You must finally use a specific SeamOperation in cunjonction with SeamRemoteObject, otherwise your conversation/task id won't be serialized:
... import org.granite.seam.SeamRemoteObject; import org.granite.seam.SeamOperation; ... srv = new SeamRemoteObject("mydestination"); var operation:SeamOperation = new SeamOperation(); operation.name = "myMethod"; operation.addEventListener(ResultEvent.RESULT, onMyMethodResult); srv.operations = {myMethod: operation}; ...
To use Seam services in your Flex application, you must configure a seam specific service factory and refer to it in your destinations:
<services-config> <services> <service id="granite-service" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage"> <!-- ! Use "seamFactory" and "my-graniteamf" for "person" destination (see below). !--> <destination id="person"> <channels> <channel ref="my-graniteamf"/> </channels> <properties> <factory>seamFactory</factory> <source>personService</source> </properties> </destination> </service> </services> <!-- ! Declare seamFactory service factory. !--> <factories> <factory id="seamFactory" class="org.granite.seam.SeamServiceFactory" /> </factories> <!-- ! Declare 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> </channels> </services-config>
Seam comes with a powerful security system named Identity. To enable Identity based security, you must customize your components.xml file by adding the following line (other configurations are of course possible, please refer to Seam documentation):
<security:identity jaas-config-name="other"/>
Then, you must tell Granite to use the Seam specific security service:
<granite-config> ... <!-- ! Use Seam based security service. !--> <security type="org.granite.seam.security.SeamSecurityService"/> </granite-config>
Finally, you'll be able to use the @Restrict security annotation as shown here:
... @Stateless @Name("mySeamService") @Scope(ScopeType.EVENT) @Local(PersonService.class) @Restrict("#{s:hasRole('user') or s:hasRole('admin')}") public class MySeamServiceBean implements MySeamService { ... public List<?> findAllThings() {...} @Restrict("#{s:hasRole('admin')}") public List<?> deleteThing(Thing thing) {...} ... }
While findAllThings method may be used by any authenticated user with the "user" or "admin" role, the deleteThing method is restricted to only users with the "admin" role.
Please note that if you are using this SeamSecurityService, you can't use standard J2EE role based security as described here (@SecurityDomain and @RolesAllowed): Seam Identity does not propagate Principal to session beans, you must only use @Restrict annotations.
In order to initialize Seam, you must also customize your web.xml as follow:
<web-app version="2.4" ...> ... <!-- ! Seam global parameters. !--> <context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.xhtml</param-value> </context-param> <context-param> <param-name>facelets.DEVELOPMENT</param-name> <param-value>true</param-value> </context-param> <!-- ! Seam servlet context listener. !--> <listener> <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> </listener> <!-- ! AMF & Seam filters (order is important!) !--> <filter> <filter-name>AMFMessageFilter</filter-name> <filter-class>org.granite.messaging.webapp.AMFMessageFilter</filter-class> </filter> <filter> <filter-name>Seam Filter</filter-name> <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class> </filter> <filter-mapping> <filter-name>AMFMessageFilter</filter-name> <url-pattern>/graniteamf/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>Seam Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- ! Faces & AMF servlets. !--> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <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>Faces Servlet</servlet-name> <url-pattern>*.seam</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AMFMessageServlet</servlet-name> <url-pattern>/graniteamf/*</url-pattern> </servlet-mapping> ... </web-app>
|
Browse Space |
Explore Confluence |
Your Account |
Add Content |
|
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.6.0 Build:#913 Sep 27, 2007) |
|
|
|