一、web.xml文件的配置
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/config/applicationContext*.xml </param-value> </context-param> <context-param> <param-name>graniteConfigPath</param-name> <param-value>/WEB-INF/granite/granite-config.xml</param-value> </context-param> <context-param> <param-name>servicesConfigPath</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <listener> <listener-class>org.granite.config.GraniteConfigListener</listener-class> </listener> <!-- SpringSecurity框架的过滤器 --> <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> <!-- GraniteDS框架的过滤器 --> <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> <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>
二、services-config.xml文件的配置
<services-config> <services> <service id="granite-service" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage"> <default-channels> <channel ref="my-graniteamf"/> </default-channels> <destination id="securityService"> <properties> <factory>spring</factory> <source>securityService</source> </properties> </destination> </service> </services> <factories> <factory id="spring" class="org.granite.spring.SpringServiceFactory"/> </factories> <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>
三、granite-config.xml文件的配置
<!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-config internal//EN" "http://www.graniteds.org/public/dtd/2.0.0/granite-config.dtd"> <granite-config> <security type="org.granite.messaging.service.security.SpringSecurityService"/> </granite-config>
四、applicationContext.xml文件的配置
<beans xmlns="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"> <bean id="securityService" class="com.achievo.web.service.SecurityServiceImpl"/> </beans>
五、applicationContext-security.xml文件的配置
<b:beans xmlns="http://www.springframework.org/schema/security" xmlns:b="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 auto-config="true" lowercase-comparisons="false" path-type="ant" access-decision-manager-ref="accessDecisionManager" access-denied-page="/index.html"> <intercept-url pattern="/index.html*" filters="none"/> <intercept-url pattern="/**/*.css*" filters="none"/> <intercept-url pattern="/**/*.js*" filters="none"/> <intercept-url pattern="/**/*.swf*" filters="none"/> <intercept-url pattern="/graniteamf/amf*" filters="none"/> <intercept-url pattern="/**" access="ADMIN"/> <form-login login-page="/index.html" authentication-failure-url="/index.html"/> <logout logout-success-url="/index.html" invalidate-session="true"/> <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="false" expired-url="/index.html"/> <remember-me /> </http> <!-- 方法级安全配置 --> <global-method-security access-decision-manager-ref="accessDecisionManager" secured-annotations="enabled" jsr250-annotations="enabled"> <protect-pointcut expression="execution(* com.achievo.web.service..*.*(..))" access="ADMIN"/> </global-method-security> <b:bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased"> <b:property name="allowIfAllAbstainDecisions" value="false"/> <b:property name="decisionVoters"> <b:list> <b:bean class="org.springframework.security.vote.RoleVoter"> <b:property name="rolePrefix" value=""/> </b:bean> </b:list> </b:property> </b:bean> <authentication-provider> <user-service> <user name="admin" password="admin" authorities="ADMIN"/> <user name="user" password="user" authorities="USER"/> </user-service> </authentication-provider> </b:beans>
六、java类源码
public interface SecurityService {
public String[] getUserRoles();
}
public class SecurityServiceImpl implements SecurityService {
public String[] getUserRoles(){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
GrantedAuthority[] ga = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
String[] roles = new String[ga.length];
for(int i=0;i<ga.length;i++){
roles[i] = ga[i].getAuthority();
}
return roles;
}
}
七、mxml文件源码
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()"> <mx:Script> <![CDATA[ import mx.messaging.Channel; import mx.messaging.ChannelSet; import mx.controls.Alert; import org.granite.events.SecurityEvent; import org.granite.rpc.remoting.mxml.SecureRemoteObject; import com.achievo.flex.common.StringUtils; import mx.rpc.Fault; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; private var roles:Array; private var src:SecureRemoteObject = null; private function init():void{ src = new SecureRemoteObject("securityService"); src.showBusyCursor = true; src.addEventListener(ResultEvent.RESULT, resultHandler); src.addEventListener(FaultEvent.FAULT, faultHandler); src.addEventListener(SecurityEvent.ALL, securityHandler); username.setFocus(); btnLogout.enabled = false; } private function login():void{ btnLogin.enabled = false; try{ src.setCredentials(username.text, password.text, "UTF-8"); src.getOperation("getUserRoles").send(); }catch(ex:Error){ errorMsg.text = "getUserRoles error: " + ex.toString(); } } private function logout():void{ src.logout(); errorMsg.text = ""; username.text = ""; password.text = ""; btnLogin.enabled = true; btnLogout.enabled = false; username.setFocus(); } private function resultHandler(e:ResultEvent):void{ errorMsg.text = "用户角色: " + e.result; btnLogin.enabled = false; btnLogout.enabled = true; } private function faultHandler(e:FaultEvent):void{ var fault:Fault = e.fault; var s:String = (fault.faultDetail!=null) ? fault.faultDetail : fault.faultString; errorMsg.text = "faultHandler: " + s; btnLogin.enabled = true; } private function securityHandler(e:SecurityEvent):void{ switch(e.type){ case SecurityEvent.INVALID_CREDENTIALS: src.logout(); errorMsg.text = "用户名或者密码不正确"; btnLogin.enabled = true; break; case SecurityEvent.NOT_LOGGED_IN: src.logout(); errorMsg.text = "尚未登录"; btnLogin.enabled = true; break; case SecurityEvent.SESSION_EXPIRED: src.logout(); errorMsg.text = "Session过期"; btnLogin.enabled = true; break; case SecurityEvent.ACCESS_DENIED: src.logout(); errorMsg.text = "没有访问权限"; btnLogin.enabled = true; break; } } ]]> </mx:Script> <mx:Panel id="p1" x="159" y="58" horizontalCenter="0" verticalCenter="0" width="359" height="332" layout="absolute" title="系统登录" fontSize="12"> <mx:VBox width="100%"> <mx:Form id="form1" x="0" y="0" width="100%" defaultButton="{btnLogin}"> <mx:FormItem label="用户名" width="100%"> <mx:TextInput id="username"/> </mx:FormItem> <mx:FormItem label="密 码" width="100%"> <mx:TextInput id="password" displayAsPassword="true"/> </mx:FormItem> </mx:Form> <mx:HBox horizontalAlign="center" width="100%" horizontalGap="19"> <mx:Button id="btnLogin" label="登录" click="login()"/> <mx:Button label="注销" id="btnLogout" click="logout()"/> </mx:HBox> </mx:VBox> <mx:Text x="10" y="136" width="319" height="111" id="errorMsg"/> </mx:Panel> </mx:Application>