浏览 5925 次
精华帖 (2) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-10-15
package flex.spring; import java.security.Principal; import java.util.List; import javax.servlet.ServletConfig; import flex.messaging.FlexContext; import flex.messaging.security.LoginCommand; import flex.messaging.security.SecurityException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.Authentication; import org.springframework.security.AuthenticationException; import org.springframework.security.context.SecurityContext; import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.context.SecurityContextImpl; import org.springframework.security.providers.AuthenticationProvider; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; /** * Custom implementation of BlazeDS LoginCommand which utilizes * Spring Security 2.0 framework underneath. * <p/> * * Date: Oct 14, 2008 * Time: 12:33:46 PM */ public class SpringSecurityLoginCommand implements LoginCommand { protected final Log log = LogFactory.getLog(getClass()); public static final String AUTHENTICATION_PROVIDER_BEAN_NAME = "authenticationProvider"; public static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT"; private final AuthenticationProvider provider; private final boolean isPerClientAuthentication; public SpringSecurityLoginCommand() { isPerClientAuthentication = FlexContext.isPerClientAuthentication(); WebApplicationContext wac = WebApplicationContextUtils .getWebApplicationContext(FlexContext.getServletContext()); provider = (AuthenticationProvider) wac.getBean(AUTHENTICATION_PROVIDER_BEAN_NAME); log.info("Spring Security Authentication Provider initialized - " + provider); } public Principal doAuthentication(String username, Object credentials) { SecurityContext securityContext; if (isPerClientAuthentication) { securityContext = (SecurityContext) FlexContext.getFlexClient() .getAttribute(SPRING_SECURITY_CONTEXT_KEY); } else { securityContext = (SecurityContext) FlexContext.getFlexSession() .getAttribute(SPRING_SECURITY_CONTEXT_KEY); } Authentication principal; if (securityContext == null) { UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, credentials); try { principal = provider.authenticate(token); securityContext = new SecurityContextImpl(); securityContext.setAuthentication(principal); if (isPerClientAuthentication) { FlexContext.getFlexClient().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); } else { FlexContext.getFlexSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext); } if (log.isDebugEnabled()) { log.debug("[Login] Security Context was created."); } } catch (AuthenticationException e) { SecurityException se = new SecurityException(); se.setMessage(SecurityException.SERVER_AUTHENTICATION_CODE); se.setRootCause(e); throw se; } } else { principal = securityContext.getAuthentication(); log.info("[" + username + "] was already authenticated previously."); } SecurityContextHolder.setContext(securityContext); return principal; } public boolean logout(Principal principal) { if (isPerClientAuthentication) { FlexContext.getFlexClient().removeAttribute(SPRING_SECURITY_CONTEXT_KEY); } else { FlexContext.getFlexSession().removeAttribute(SPRING_SECURITY_CONTEXT_KEY); } SecurityContextHolder.getContext().setAuthentication(null); if (log.isDebugEnabled()) { log.debug("[Logout] Security Context was removed."); } return true; } public boolean doAuthorization(Principal principal, List list) { // always return TRUE as the authorization is delegated to Spring Security. return true; } public void start(ServletConfig config) { // noop } public void stop() { // noop } } services-config.xml------------------------------ <?xml version="1.0" encoding="ISO-8859-1"?> <services-config> <services> <service-include file-path="remoting-config.xml" /> </services> <factories> <factory id="spring" class="adobe.flex.sample.SpringFactory" /> </factories> <security> <login-command class="flex.spring.SpringSecurityLoginCommand" server="all"> <per-client-authentication>true</per-client-authentication> </login-command> <security-constraint id="default"> <auth-method>Custom</auth-method> </security-constraint> </security> <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> </channels> <logging> <target class="flex.messaging.log.ConsoleTarget" level="Info"> <properties> <prefix>[BlazeDS] </prefix> <includeDate>false</includeDate> <includeTime>false</includeTime> <includeLevel>true</includeLevel> <includeCategory>true</includeCategory> </properties> <filters> <pattern>Endpoint.*</pattern> <pattern>Service.*</pattern> <pattern>Configuration</pattern> </filters> </target> </logging> <system> <redeploy> <enabled>false</enabled> </redeploy> </system> </services-config> remoting-config.xml----------------------------- <?xml version="1.0" encoding="ISO-8859-1"?> <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="roles"> <properties> <factory>spring</factory> <source>roles</source> <scope>session</scope> </properties> <security> <security-constraint ref="default" /> </security> </destination> </service> spring-config.xml------------------------------ <?xml version="1.0" encoding="ISO-8859-1"?> <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.xsd"> <bean id="authenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider"> <property name="userDetailsService"> <bean class="org.springframework.security.userdetails.memory.InMemoryDaoImpl"> <property name="userMap"> <value> david=password,ROLE_ADMIN alex=password,ROLE_USER </value> </property> </bean> </property> </bean> <bean id="hello" class="flex.spring.SecurityRoles" /> </beans> java ------------------------ package flex.spring; import org.springframework.security.Authentication; import org.springframework.security.GrantedAuthority; import org.springframework.security.context.SecurityContextHolder; public class SecurityRoles { public String allowedAuthorities() { Authentication principal = SecurityContextHolder.getContext().getAuthentication(); StringBuilder result = new StringBuilder(); for (GrantedAuthority ga : principal.getAuthorities()) { result.append(",").append(ga.getAuthority()); } return result.substring(1); } } Flex Client--------------------------------------- <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="100%" height="100%" creationComplete="init()"> <mx:Script> <![CDATA[ import mx.controls.Alert; import mx.messaging.config.ServerConfig; import mx.rpc.AsyncToken; import mx.rpc.AsyncResponder; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.messaging.ChannelSet; // Define a ChannelSet object. public var cs:ChannelSet; // Define an AsyncToken object. public var token:AsyncToken; // Initialize ChannelSet object based on the // destination of the RemoteObject component. private function init():void { if (cs == null) cs = ServerConfig.getChannelSet(remoteObject.destination); } // Login and handle authentication success or failure. private function ROLogin():void { // Make sure that the user is not already logged in. if (cs.authenticated == false) { token = cs.login("alex", "password"); // Add result and fault handlers. token.addResponder(new AsyncResponder(LoginResultEvent, LoginFaultEvent)); } } // Handle successful login. private function LoginResultEvent(event:ResultEvent, token:Object=null):void { switch(event.result) { case "success": authenticatedCB.selected = true; default: } } // Handle login failure. private function LoginFaultEvent(event:FaultEvent, token:Object=null):void { switch(event.fault.faultCode) { case "Client.Authentication": default: authenticatedCB.selected = false; } } // Logout and handle success or failure. private function ROLogout():void { // Add result and fault handlers. token = cs.logout(); token.addResponder(new AsyncResponder(LogoutResultEvent,LogoutFaultEvent)); } // Handle successful logout. private function LogoutResultEvent(event:ResultEvent, token:Object=null):void { switch (event.result) { case "success": authenticatedCB.selected = false; default: } } // Handle logout failure. private function LogoutFaultEvent(event:FaultEvent, token:Object=null):void { Alert.show("Logout failure: " + event.fault.faultString); } // Handle message recevied by RemoteObject component. private function resultHandler(event:ResultEvent):void { ta.text += "Congratulations! You've got server response: "+ event.result + "\n"; } // Handle fault from RemoteObject component. private function faultHandler(event:FaultEvent):void { ta.text += "Oops! Something wrong: " + event.fault + "\n"; } ]]> </mx:Script> <mx:HBox height="45"> <mx:Button label="Login" click="ROLogin()"/> <mx:Button label="What roles do I have?" enabled="{authenticatedCB.selected}" click="remoteObject.allowedAuthorities()"/> <mx:Button label="Logout" click="ROLogout()"/> <mx:CheckBox id="authenticatedCB" label="Authenticated?" enabled="true"/> </mx:HBox> <mx:TextArea id="ta" width="100%" height="511"/> <mx:RemoteObject id="remoteObject" destination="hello" result="resultHandler(event)" fault="faultHandler(event)"/> </mx:Application> The end----------------------------------- 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-02-26
很好很详细,对我挺有帮助。
建议前面加个代码文件列表,思路概要,代码部分使用codestyle方便阅读。 |
|
返回顶楼 | |