Spring MVC+BlazeDS+Flex框架实践:Security篇

    在Spring MVC+BlazeDS+Flex框架实践:Database篇的基础上,这次要加入的是Spring Security的配置与应用。至于Spring Security的原理及配置详解网上已经有很多可参考的文章,在这里就不再重复了。

一、Spring Security配置

1)添加Application-Security.xml

在JAVA工程src下创建Application-Security.xml
userName

2)修改web.xml

在添加Application-Security.xml后,需要在web.xml中将其添加到初始化加载列表中
修改web.xml以下配置:
contextConfigLocation classpath:ApplicationContext.xml,classpath:Application-Flex.xml,classpath:Application-hibernate.xml,classpath:Application-Security.xml

 

二、Security类创建

在JAVA工程src下创建package com.common.security

创建SecurityLogListener.java

package com.common.security; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.security.event.authentication.AbstractAuthenticationEvent; import org.springframework.security.event.authentication.AuthenticationSuccessEvent; import org.springframework.security.event.authentication.InteractiveAuthenticationSuccessEvent; import org.springframework.security.ui.WebAuthenticationDetails; import org.springframework.security.ui.session.HttpSessionApplicationEvent; import org.springframework.security.ui.session.HttpSessionDestroyedEvent; import com.common.hibernate.GenericService; import flex.messaging.FlexContext; public class SecurityLogListener implements ApplicationListener { private static final Log logger = LogFactory.getLog(SecurityLogListener.class); GenericService genericService; public GenericService getGenericService() { return genericService; } public void setGenericService(GenericService genericService) { this.genericService = genericService; } public void onApplicationEvent(ApplicationEvent event) { if (event instanceof AbstractAuthenticationEvent) { try { AbstractAuthenticationEvent authEvent = (AbstractAuthenticationEvent) event; if (event instanceof AuthenticationSuccessEvent) { Object obj = authEvent.getAuthentication().getPrincipal(); if (obj instanceof FlexUserDetails) { System.out.println("Username: "+((FlexUserDetails) obj).getUsername()); System.out.println("Login Date: "+new Date()); System.out.println("Session Id: "+FlexContext.getFlexSession().getId()); } } else if (event instanceof InteractiveAuthenticationSuccessEvent) logger.warn("InteractiveAuthenticationSuccessEvent:" + authEvent.getAuthentication().getDetails()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if (event instanceof HttpSessionApplicationEvent) { HttpSessionApplicationEvent sessionEvent = (HttpSessionApplicationEvent) event; if (event instanceof HttpSessionDestroyedEvent) { logger.info("[destroy]"+sessionEvent.getSession().getId()); Map params = new HashMap(); params.put("sessionId", sessionEvent.getSession().getId()); System.out.println("Session Id: "+sessionEvent.getSession().getId()); System.out.println("Session remove date: "+new Date()); }else logger.info("[create]"+sessionEvent.getSession().getId()); } } }

 

创建SecurityLogoutHandler.java
package com.common.security; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.Authentication; import org.springframework.security.ui.logout.SecurityContextLogoutHandler; import com.common.hibernate.GenericService; public class SecurityLogoutHandler extends SecurityContextLogoutHandler { private static final Log logger = LogFactory.getLog(SecurityLogoutHandler.class); GenericService genericService; public SecurityLogoutHandler() { super(); } public GenericService getGenericService() { return genericService; } public void setGenericService(GenericService genericService) { this.genericService = genericService; } public void logout(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse, Authentication authentication) { try { Map params = new HashMap(); params.put("sessionId", httpservletrequest.getSession().getId()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } super.logout(httpservletrequest, httpservletresponse, authentication); } }

 

创建FlexUserDetails.java

此类中的信息与数据库的结构有关
package com.common.security; import java.util.Date; import org.springframework.security.GrantedAuthority; import org.springframework.security.userdetails.UserDetails; import com.admin.domain.FrameworkUser; public class FlexUserDetails implements UserDetails { private FrameworkUser fu; private GrantedAuthority[] authorities; public FlexUserDetails(FrameworkUser user,GrantedAuthority[] roles){ this.fu=user; this.authorities=roles; } public GrantedAuthority[] getAuthorities() { return authorities; } public String getPassword() { return fu.getUserPassword(); } public String getUsername() { // TODO Auto-generated method stub return fu.getUserName(); } public boolean isAccountNonExpired() { return true; } public boolean isAccountNonLocked() { // TODO Auto-generated method stub return true; } public boolean isCredentialsNonExpired() { // TODO Auto-generated method stub return true; } public boolean isEnabled() { Date now=new Date(); return fu.getStartDateActive().before(now)&&(fu.getEndDateActive()==null||fu.getEndDateActive().after(now)); } public FrameworkUser getFu() { return fu; } public void setFu(FrameworkUser fu) { this.fu = fu; } public void setAuthorities(GrantedAuthority[] authorities) { this.authorities = authorities; } }

 

创建FlexUserDetailsService.java
     此类中具体执行了用户登录时的授权等操作,其中明确了当用户为"admin"时,为其授予ROLE_ADMIN、ROLE_USER、ROLE_ANONYMOUS权限;而其他用户则只有ROLE_USER、ROLE_ANONYMOUS权限。不同权限的访问范围在Application-Security.xml中进行控制。本例中只有ROLE_ADMIN权限的角色才能访问modules/admin下的页面。
package com.common.security; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.springframework.context.support.MessageSourceAccessor; import org.springframework.dao.DataAccessException; import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthorityImpl; import org.springframework.security.SpringSecurityMessageSource; import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.UserDetailsService; import org.springframework.security.userdetails.UsernameNotFoundException; import com.admin.domain.FrameworkUser; import com.common.hibernate.GenericService; public class FlexUserDetailsService implements UserDetailsService { private static final Logger logger = Logger.getLogger(AuthenticationHelper.class); private GenericService genericService; private String userNameProperty; protected MessageSourceAccessor messages; private String authoritiesbyUsernameQuery; public FlexUserDetailsService() { messages = SpringSecurityMessageSource.getAccessor(); } public GenericService getGenericService() { return genericService; } public void setGenericService(GenericService genericService) { this.genericService = genericService; } public String getUserNameProperty() { return userNameProperty; } public void setUserNameProperty(String userNameProperty) { this.userNameProperty = userNameProperty; } public String getAuthoritiesbyUsernameQuery() { return authoritiesbyUsernameQuery; } public void setAuthoritiesbyUsernameQuery(String authoritiesbyUsernameQuery) { this.authoritiesbyUsernameQuery = authoritiesbyUsernameQuery; } public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException, DataAccessException { System.out.println("UserDetails: loadUserByUsername"); List users = new ArrayList(); try { users = this.loadUsersByUsername(name); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } if (users.size() == 0) throw new UsernameNotFoundException(messages.getMessage("JdbcDaoImpl.notFound", new Object[] { name }, "Username {0} not found"), name); FrameworkUser user = (FrameworkUser) users.get(0); GrantedAuthority[] roles = loadUserAuthorities(name); if (roles == null) throw new UsernameNotFoundException(messages.getMessage("JdbcDaoImpl.noAuthority", new Object[] { name }, "User {0} has no GrantedAuthority"), name); logger.info("roles " + roles.length); logger.info("login in success," + user.getUserName()); return new FlexUserDetails(user, roles); } private List loadUsersByUsername(String name) throws Exception { System.out.println("List: loadUserByUsername"); Map params = new HashMap(); params.put(this.userNameProperty, name); return genericService.findByProperty(FrameworkUser.class.getName(), params); } private GrantedAuthority[] loadUserAuthorities(String name) { Map params = new HashMap(); params.put("userName", name); List roles = new ArrayList(); if(name.equals("admin")){ roles.add(new GrantedAuthorityImpl(name)); roles.add(new GrantedAuthorityImpl("ROLE_ANONYMOUS")); roles.add(new GrantedAuthorityImpl("ROLE_ADMIN")); roles.add(new GrantedAuthorityImpl("ROLE_USER")); System.out.println("授权: ROLE_ADMIN,ROLE_ANONYMOUS"); }else{ roles.add(new GrantedAuthorityImpl(name)); roles.add(new GrantedAuthorityImpl("ROLE_ANONYMOUS")); roles.add(new GrantedAuthorityImpl("ROLE_USER")); System.out.println("授权: ROLE_USER,ROLE_ANONYMOUS"); } GrantedAuthority[] authoritiesarray = new GrantedAuthority[roles.size()]; roles.toArray(authoritiesarray); return authoritiesarray; } }

 

创建AuthenticationHelper.java

     此类在用户登录时被调用

package com.common.security; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import org.springframework.security.Authentication; import org.springframework.security.AuthenticationManager; import org.springframework.security.GrantedAuthority; import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.userdetails.UserDetails; import flex.messaging.FlexContext; public class AuthenticationHelper { private static final Logger logger = Logger.getLogger(AuthenticationHelper.class); private AuthenticationManager authenticationManager; public AuthenticationManager getAuthenticationManager() { return authenticationManager; } public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } public void authenticatePrincipal(String username, String password) { //try{ logger.info("user login system! username:" + username); UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken( username, password); Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken); SecurityContextHolder.getContext().setAuthentication(authentication); GrantedAuthority[] authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities(); int numAuthorities = authorities.length; String[] grantedRoles = new String[numAuthorities]; for (int counter = 0; counter < numAuthorities; counter++) { grantedRoles[counter] = authorities[counter].getAuthority(); } String name = SecurityContextHolder.getContext().getAuthentication().getName(); logger.info("登录成功!"); //}catch(Exception e){e.printStackTrace();} } public Map getCurrentUser() { if (SecurityContextHolder.getContext() == null || SecurityContextHolder.getContext().getAuthentication() == null || SecurityContextHolder.getContext().getAuthentication().getPrincipal() == null) { Map temp = new HashMap(); temp.put("userName", "System"); temp.put("userId", 0); return temp; } Map user = new HashMap(); Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (obj instanceof UserDetails) { user.put("userDescription", ((FlexUserDetails) obj).getFu().getUserDescription()); user.put("userId", ((FlexUserDetails) obj).getFu().getUserId()); user.put("userName", ((FlexUserDetails) obj).getUsername()); } else { user.put("userName", obj.toString()); user.put("userId", -100); } logger.info(user); return user; } public Long getCurrentUserId() { if (this.getCurrentUser().get("userId") != null) return Long.valueOf(this.getCurrentUser().get("userId").toString()); return new Long(-100); } }

 

三、配置AuthenticationHelper

1)发布AuthenticationHelper

在Application-Flex.xml中添加如下配置:

2)创建CommonModule.mxml

在FLEX工程modules/common目录下创建CommonModule.mxml,用以实现Security验证

3)引用authenticationHelper
在FLEX工程remoting-config.xml中添加如下配置:
authenticationHelper

3)修改Index.mxml

在Index.mxml中调用authenticationHelper,修改后的Index.mxml内容如下:

 

四、编译运行
1)编译FLEX工程
选择Project—>Clean—>TestProject

2)拷贝FLEX编译目录bin-debug/modules到JAVA工程WebRoot下

3)启动本地数据库

4)启动服务器

5)服务器正常启动后,在浏览器内输入(其中9090为服务器端口号)

http://localhost:9090/TestProject/modules/common/Index.html

 

运行结果:
以Sky用户登录

Spring MVC+BlazeDS+Flex框架实践:Security篇_第1张图片

 

登录首页
Spring MVC+BlazeDS+Flex框架实践:Security篇_第2张图片

 

查看modules/admin/UserModule.swf,由于权限控制将无法访问

Spring MVC+BlazeDS+Flex框架实践:Security篇_第3张图片

 

查看modules/common/CommonModule.swf

Spring MVC+BlazeDS+Flex框架实践:Security篇_第4张图片

 

以admin用户登录

Spring MVC+BlazeDS+Flex框架实践:Security篇_第5张图片

 

查看modules/admin/UserModule/swf,由于已经为该用户授予了权限,因此可以访问

Spring MVC+BlazeDS+Flex框架实践:Security篇_第6张图片

 

查看modules/common/CommonModule.swf

Spring MVC+BlazeDS+Flex框架实践:Security篇_第7张图片

 

 

到此Spring MVC+BlzeDS+Flex框架的搭建三个过程都已经结束,如果今后还有新的内容我会及时和大家分享。

 

你可能感兴趣的:(security,spring,flex,mvc,框架,authentication,Java,Web,Flex,Sping)