当前位置: 首页 > 工具软件 > GraniteDS > 使用案例 >

Flex + GraniteDS + Spring + SpringSecurity的整合

鲍理
2023-12-01

一、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>

 

 类似资料: