blazeds+stping

http://www.riadev.com/flex-thread-450-1-1.html

如今,每个应用程序都必须考虑安全问题。安全涵盖广泛的领域,本文仅重点介绍应用程序安全性,更具体来讲就是用户身份验证和授权。身份验证用于确认用户具有他声明的身份,而授权用于确认当前用户具有执行他希望执行的操作的权限。

为了解释这些概念,本文使用一个管理和显示图书列表的示例Flex应用程序。这个Flex客户端使用BlazeDS与一个服务器通信,该服务器运行着另一个使用Spring框架开发的应用程序。这个示例是一个完整的应用程序,演示了在客户端上保护使用Flex的应用程序的许多方面。

Spring框架提供的一个模块是Spring Security(以前称为Acegi)。Spring Security模块负责对远程服务进行身份验证以及授权。我不打算重点介绍Spring集成,因为Sébastien Arbogast已经在Adobe Developer Connection上名为"The Flex, Spring, and BlazeDS full stack"的系列文章中介绍了这一主题。

要求

Flex Builder

  • 试用
  • 购买

BlazeDS

  • 下载试用版

Spring

  • Download

Maven

  • Download

JDK 6

  • Download

示例文件

  • flex_security.zip (ZIP, 75K)

预备知识

要求对Flex事件模型、Java Web应用程序和Spring框架有基本的了解。

参考资料

The Flex, Spring, and BlazeDS full stack:

  • 创建一个Flex组件
  • 写出代办服务列表
  • 集成所有应用
  • 确保您的Flex应用与Spring Security 和 Active Directory
  • BlazeDS, Spring, 和 Acegi Security – 第三部分

安全问题

简单而言,安全应用程序必须首先知道您是谁,然后知道您可以做什么。应用程序使用身份验证来确保您具有您表明的身份,使用授权来确定您是否拥有执行您尝试执行的操作的权限。对于Web应用程序,身份验证是一个众所周知的领域。有许多身份验证方法,包括用户名/密码、虹膜扫描、指纹和令牌。

身份验证在富客户端(包括使用Flex开发的客户端)中的工作方式相同。但是,如果您创建的应用程序也将离线运行(比如Adobe AIR应用程序),那么需要考虑一些限制。举例而言,示例应用程序使用了一个将在服务器上检查的用户名/密码组合。因此您不能在没有网络连接的情况下使用该应用程序。另请注意,由于它是个基本示例,所以没有使用HTTPS或通常实现来保护应用程序的其他加密形式。

解决方案的总体架构

示例应用程序包含两个主要部分——客户端和服务器。客户端的架构简单明了。它是一个Flex组件,部署为SWF文件。服务器组件比较复杂(参见图1)。

图1. 常见Web应用程序架构的总体概述。绿框是Spring框架模块,红框是Adobe模块,蓝框是自定义模块。

图字

  • Browser:浏览器
  • Flex client:Flex客户端
  • Servlet container:Servlet容器
  • Spring security (url based):Spring安全机制(基于URL)
  • Spring security (method level):Spring安全机制(方法级)
  • Business Services:业务服务
  • Data access:数据访问

在图1中的服务器部分,绿框是Spring框架模块,红框是Adobe模块,蓝框是自定义模块(但它们也包含Spring功能)。这些类使用Spring应用程序上下文相连接,事务的配置基于服务方法,还配置了方法级安全性等。因为本文重点介绍Flex集成,所以我不打算详述Spring细节。但是,我将解释安全性配置。从图1中可以看到,在两个位置使用了Spring安全性。第一处是通过筛选URL拦截Web调用。第二处是保护方法调用。因为我使用BlazeDS直接向Flex客户端公开了Spring bean,所以这种方法级安全性非常重要。

示例

示例应用程序显示一个图书列表,可以对它进行筛选和排序。为了演示不同角色的使用,只有管理员(admin)可以添加新图书。示例使用Maven构建WAR文件和Flex SWF文件。关于如何构建的更多信息,请参见Sébastien Arbogast在http://www.adobe.com/devnet/flex/articles/fullstack_pt3.html上的文章。图2概述了应用程序的不同组件。

图2. 示例应用程序的组件图。黄色组件为JAR文件,蓝色为WAR文件,红色为Flex SWF文件,灰色仅用于配置用途。WAR文件是将包含所有其他组件的可部署单元。

设置服务器组件

因为Sébastien Arbogast的系列文章解释了如何配置Flex、BlazeDS和Spring来让它们协同工作。这里仅简单介绍一下。要配置的第一项是web.xml文件。

  SpringSecurityFilterChain   org.Springframework.web.filter.DelegatingFilterProxy   SpringSecurityFilterChain   /*

web.xml文件的这一部分显示了拦截所有URL的Spring安全筛选器的配置。web.xml文件还配置BlazeDS服务和Spring上下文。参见这些小节的代码示例。下一步是配置URL和要保护的方法。以下Spring配置是Spring-security.xml文件中的一部分,可以在示例代码中找到。

                       

该配置包含3部分。第一部分是security:http,配置基于URL的访问控制。Spring安全机制在第2版中得到了巨大改进,引入了命名空间以及许多合理的默认设置。从配置中可以看到(),我选择了不保护Flex组件,所以所有访问者都可以下载该组件。这是在您的Flex应用程序中设置登录的最合理方式。

第二部分配置方法级安全性。您可以使用方面和切入点表达式(pointcut expression)语言配置要保护哪些方法。(详细介绍该表达式语言不属于本文介绍范围。)如果您仔细查看,可以看到我保护了以"Manager"结尾且以"store"开头的对象的所有方法。只有admin可以调用这些方法。相同对象的所有"obtain"方法都需要user角色。

第三部分是身份验证提供方。为简单起见,我使用了已提供了内存型存储。可以看到,定义了两个用户——user和admin。admin具有两种角色,而user仅具有ROLE_USER角色。只有admin可以调用一个store方法来创建新图书。

设置FLEX和BLAZEDS

Flex客户端与BlazeDS之间的连接在两个配置文件中指定。第一个文件是services-config.xml,它包含创建远程对象代理的渠道和工厂的配置。我使用的Spring工厂与Arbogast文章中介绍的相同。使用此工厂,我们可以访问配置bean的Spring框架。services-config.xml文件还包含对另一个配置文件remoting-config.xml的引用。此配置文件包含要调用的目标或实际的远程bean。以下代码显示了我在示例中使用的目标:

      Spring     bookManager         nl.gridshore.samples.books.web.security.AuthenticationHelper  

bookManager目标是一个Spring bean,它公开用户可以调用来获取图书和创建新图书的方法。可以看到,我使用Spring工厂来访问此目标。authenticationHelper目标不是Spring bean,但它提供了与该框架的挂钩。这个bean用于对用户进行身份验证并获取经过验证的用户的角色。下一部分代码展示了的方法接受用户名和密码,然后要求身份验证管理器使用这些凭证对特定主体进行身份验证。

public AuthorizationData authenticatePrincipal(String usr, String pwd) {   ApplicationContext appContext =WebApplicationContextUtils.getWebApplicationContext(       FlexContext.getServletConfig().getServletContext());   AuthenticationManager manager =       (AuthenticationManager)appContext.getBean("_authenticationManager");   UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =       new UsernamePasswordAuthenticationToken(username,password);   Authentication authentication = manager.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();   return new AuthorizationData(grantedRoles,name); }

因为这是理解与Spring安全机制的集成的最重要的一部分,我将分解这段代码来解释其内部原理。

WebApplicationContextUtils.getWebApplicationContext(     FlexContext.getServletConfig().getServletContext());

使用FlexContext类,我们可以访问当前的ServletContext,它提供了访问Spring框架应用程序上下文的途径。示例使用了Spring Security配置的命名空间支持。根据配置约定,使用名称_authenticationManager在Spring上下文中注册了一个authenticationManager bean。

AuthenticationManager manager =     (AuthenticationManager)appContext.getBean("_authenticationManager");

下一步是根据提供的用户名和密码创建身份验证令牌。此令牌用于调用身份验证管理器上的身份验证方法来验证主体。返回的验证结果被添加到进行下一次调用时需要记住和使用的会话中。

Authentication authentication = manager.authenticate(usernamePasswordAuthenticationToken); SecurityContextHolder.getContext().setAuthentication(authentication);

在下一步中,为Flex客户端提供了为经过身份验证的用户授予的角色。获取了角色和实际的用户名之后,应用程序创建一个AuthorizationData对象,然后将该对象返回给调用方和使用BlazeDS的Flex客户端。

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(); return new AuthorizationData(grantedRoles,name);

创建远程对象

当与服务器通信时,Flex使用RemoteObject组件。因为在与服务器通信时许多地方可能出错,我想要一种一般机制来处理这些问题。我创建了一个对象结构,它使用RemoteObject组件并处理为其分派的事件。我使用事件来处理错误和通知其他组件。

图3显示了用于创建此一般机制的类。

图3. 远程对象通信过程中涉及的最重要类的概述。黄色的类是Flex框架类,绿色的是自定义类,蓝色的是事件。

你可能感兴趣的:(blazeds+stping)