Tuscany Home
 

OSGi环境下结合Spring对Acegi的集成

From Tuscany中文社区

Jump to: navigation, search

目录

[编辑] Acegi安全系统介绍

Acegi是Spring Framework 下的安全系统,它提供了强大灵活的企业级安全服务,如完善的认证和授权机制,Http资
源访问控制,Method 调用访问控制,Access Control List (ACL) 基于对象实例的访问控制,Yale Central 
Authentication Service (CAS) 耶鲁单点登陆,X509 认证,当前所有流行容器的认证适配器,Channel Security
频道安全管理等功能。

[编辑] 1.Acegi是非入侵式安全的架构

  • 基于Servlet Filter和Spring aop, 使商业逻辑和安全逻辑分开,结构更清晰
  • 使用Spring 来代理对象,能方便地保护方法调用

[编辑] 2.Acegi可以进行多方面的安全控制粒度

  • URL 资源访问控制
http://apps:8080/index.htm -> for public
http://apps:8080/user.htm -> for authorized user 
  • 方法调用访问控制
public void getData() -> all user
public void modifyData() -> supervisor only 
  • 对象实例保护
order.getValue() < $100 -> all user
order.getValue() > $100 -> supervisor only


[编辑] Acegi在传统运行环境下与OSGi环境下的对比

在传统Java运行环境中,虽然Acegi 没有要求必须使用Spring Framework,但事实上Acegi很大程度上利用了Spring的IOC和AOP,很难脱离Spring的单独使用。下图是传统web环境下Servlet与Spring结合使用acegi的示意图。acegi由Spring启动保存在ApplicationContext中,FilterToBeanProxy提供获取Spring ApplicationContext的能力,同时在servlet中被实例化。

Image:Servlet Spring acegi.JPG

在OSGi环境下Acegi也同样依赖Spring框架发挥作用。OSGi环境下Acegi的配置与传统Java环境下没有特
别的变化。因此OSGi环境下的Acegi的配置是在Spring-osgi基础上的。
*在Spring的启动配置文件中描述了acegi的filters,acegi的filters被加载到Spring环境中,保存在ApplicationContext对象内。
*Spring ApplicationContext对象通过web application传给FilterToBeanProxy(图中从Spring bundle 
context指向FilterToBeanProxy的虚线),同时将 acegi中接受web请求的servlet注册到web服务器--jetty上。(从FilterToBeanProxy上面指向jetty bundle的虚线)。
*通过web application将FilterToBeanProxy注册到web服务器上。

Image:OSGi Spring acegi.JPG

[编辑] OSGi环境下实现Acegi的环境准备

[编辑] 说明

本文中Acegi的运行环境建立在在eclipse中配置基于OSGi的webx项目之上。
但是下面的步骤完全可以不依赖于以上的环境使用Acegi。

[编辑] 制作acegi的bundle

acegi bundle的制作是在原来acegi提供的jar的基础上在jar文件中的Manifest.MF文件增加OSGi的内容。
对acegi的jar文件中Manifest.MF的修改,包括导出acegi包含的包名、引入 javax.servlet、org.apache.commons.logging和支持Spring相关的包名。
修改acegi-security-1.0.3.jar 或者其他版本的acegi.XXX.jar的Manifest.MF,如下:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Acegi Plug-in
Bundle-SymbolicName: OSGi.acegi
Bundle-Version: 1.0.0
Export-Package: org.acegisecurity,
 org.acegisecurity.acl,
 org.acegisecurity.acl.basic,
 org.acegisecurity.acl.basic.cache,
 org.acegisecurity.acl.basic.jdbc,
 org.acegisecurity.acls,
 org.acegisecurity.acls.domain,
 org.acegisecurity.acls.jdbc,
 org.acegisecurity.acls.objectidentity,
 org.acegisecurity.acls.sid,
 org.acegisecurity.adapters,
 org.acegisecurity.afterinvocation,
 org.acegisecurity.captcha,
 org.acegisecurity.concurrent,
 org.acegisecurity.context,
 org.acegisecurity.context.httpinvoker,
 org.acegisecurity.context.rmi,
 org.acegisecurity.event.authentication,
 org.acegisecurity.event.authorization,
 org.acegisecurity.intercept,
 org.acegisecurity.intercept.method,
 org.acegisecurity.intercept.method.aopalliance,
 org.acegisecurity.intercept.method.aspectj,
 org.acegisecurity.intercept.web,
 org.acegisecurity.ldap,
 org.acegisecurity.ldap.search,
 org.acegisecurity.providers,
 org.acegisecurity.providers.anonymous,
 org.acegisecurity.providers.cas,
 org.acegisecurity.providers.cas.cache,
 org.acegisecurity.providers.cas.populator,
 org.acegisecurity.providers.cas.proxy,
 org.acegisecurity.providers.cas.ticketvalidator,
 org.acegisecurity.providers.dao,
 org.acegisecurity.providers.dao.cache,
 org.acegisecurity.providers.dao.salt,
 org.acegisecurity.providers.encoding,
 org.acegisecurity.providers.jaas,
 org.acegisecurity.providers.jaas.event,
 org.acegisecurity.providers.ldap,
 org.acegisecurity.providers.ldap.authenticator,
 org.acegisecurity.providers.ldap.populator,
 org.acegisecurity.providers.rcp,
 org.acegisecurity.providers.rememberme,
 org.acegisecurity.providers.siteminder,
 org.acegisecurity.providers.x509,
 org.acegisecurity.providers.x509.cache,
 org.acegisecurity.providers.x509.populator,
 org.acegisecurity.runas,
 org.acegisecurity.securechannel,
 org.acegisecurity.taglibs.authz,
 org.acegisecurity.taglibs.velocity,
 org.acegisecurity.ui,
 org.acegisecurity.ui.basicauth,
 org.acegisecurity.ui.cas,
 org.acegisecurity.ui.digestauth,
 org.acegisecurity.ui.logout,
 org.acegisecurity.ui.rememberme,
 org.acegisecurity.ui.savedrequest,
 org.acegisecurity.ui.session,
 org.acegisecurity.ui.switchuser,
 org.acegisecurity.ui.webapp,
 org.acegisecurity.ui.x509,
 org.acegisecurity.userdetails,
 org.acegisecurity.userdetails.jdbc,
 org.acegisecurity.userdetails.ldap,
 org.acegisecurity.userdetails.memory,
 org.acegisecurity.util,
 org.acegisecurity.vote,
 org.acegisecurity.wrapper
Import-Package: javax.servlet;version="2.4.0",
 javax.servlet.http;version="2.4.0",
 org.apache.commons.logging,
 org.springframework.beans;version="2.5.1",
 org.springframework.beans.factory;version="2.5.1",
 org.springframework.context;version="2.5.1",
 org.springframework.context.support;version="2.5.1",
 org.springframework.core;version="2.5.1",
 org.springframework.dao;version="2.5.1",
 org.springframework.util;version="2.5.1",
 org.springframework.web.bind;version="2.5.1",
 org.springframework.web.context.support;version="2.5.1"

[编辑] 在web应用的bundle中做设置

  • 声明acegi的xml配置文件
  • 引用acegi的bundle

说明:由于acegi要依赖Spring的环境加载,因此要在Spring的配置文件中声明acegi的初始化环境参数。这样在Spring启动时将acegi相关的环境加载。 配置如下:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Web Plug-in
Bundle-SymbolicName: book.web
Bundle-Version: 1.0.0
Spring-Context: spring.xml,applicationContext-acegi-security.xml
Require-Bundle: org.eclipse.equinox.http.helper;version="1.0.0",
 org.eclipse.equinox.http.jetty,
 org.eclipse.equinox.http.servlet,
 org.eclipse.equinox.http.registry,
 org.mortbay.jetty,
 javax.servlet.jsp,
 org.eclipse.equinox.jsp.jasper,
 org.eclipse.osgi,
 org.eclipse.osgi.services,
 org.eclipse.equinox.http.helper,
 org.eclipse.equinox.jsp.jasper.registry,
 org.springframework.bundle.osgi.core,
 org.springframework.bundle.osgi.io,
 org.springframework.bundle.osgi.extender,
 org.springframework.bundle.spring.aop,
 org.springframework.bundle.spring.beans,
 org.springframework.bundle.spring.context,
 org.springframework.bundle.spring.core,
 org.apache.jasper,
 book.service,
 org.apache.log4j,
 webx.core,
 org.apache.struts,
 org.apache.commons.el,
 org.apache.commons.logging,
 org.springframework.osgi.commons-beanutils.osgi,
 org.springframework.osgi.commons-collections.osgi,
 org.springframework.bundle.spring.web,
 OSGi.acegi
Import-Package: javax.servlet;version="2.4.0",
 javax.servlet.http;version="2.4.0",
 org.apache.commons.beanutils,
 org.apache.commons.beanutils.converters;version="1.7.0",
 org.apache.commons.collections;version="3.2.0",
 org.apache.commons.digester,
 org.apache.commons.lang,
 org.apache.commons.lang.math,
 org.osgi.framework;version="1.3.0",
 org.springframework.dao;version="2.5.1"
Bundle-ClassPath: .,
 extremecomponents-1.0.1.jar,
 jstl-1.1.2.jar,
 standard-1.1.2.jar,
 struts-1.2.9.jar

[编辑] 编写自己的FilterToBeanProxy

在传统的运行环境中,acegi的filter要从Spring ApplicationContext中获取。ApplicationContext中的内容是
由Spring容器完成加载和初始化的,使用的都是Spring本身的参数。
但是在equinox环境中,Spring是作为bundle加载到环境中的,所以Spring ApplicationContext需要从equinox环境
中获取。这里重写了acgi中FilterToBeanProxy类的getContext()方法,直接提供equinox环境中的ApplicatonContext变量。
ApplicationContext变量ac是在bundle初始化的时候,通过Spring的ApplicationContext接口提供的setApplicationContext()方法传入的。

package cn.org.tuscany.acegi.test;

import javax.servlet.FilterConfig;
import org.springframework.context.ApplicationContext;
import org.acegisecurity.util.*;

public class MyFilterToBeanProxy extends FilterToBeanProxy {

	public static ApplicationContext ac;

	/**
	 * 
	 * @param filterConfig
	 * @return
	 */
	protected ApplicationContext getContext(FilterConfig filterConfig) {

		return ac;
	}
}

[编辑] 注册到jetty中

在原有的MyContextAware的addingService方法中加入对acegi访问路径的注册。
MyContextAware 继承了Spring的ApplicationContextAware 和 BundleContextAware,
见在eclipse中配置基于OSGi的webx项目的介绍。
public class MyContextAware implements BundleContextAware,
	ApplicationContextAware {

public Object addingService(ServiceReference reference) { 
   .
   .
   .
   //代码片断
    Properties filterParam = new Properties();
   filterParam.put("targetClass","org.acegisecurity.util.FilterChainProxy");
 
   MyFilterToBeanProxy mfpFilter = new MyFilterToBeanProxy();

   FilterServletAdaptor fsa = new FilterServletAdaptor(mfpFilter,filterParam,adaptedActionServlet);
   FilterServletAdaptor fsb = new FilterServletAdaptor(mfpFilter,filterParam,adaptedActionServlet);
				
   httpService.registerServlet("/web/*.do",fsa,initparams, commonContext);
   httpService.registerServlet("/web/j_acegi_security_check",fsb,initparams,commonContext);
   .
   .
   .
 }

  public void setApplicationContext(ApplicationContext ac)
     throws BeansException {
	  DelegatingRequestProcessor.ac = ac;
	  org.tuscany.test.MyFilterToBeanProxy.ac=ac;
  }


}

[编辑] 原理和对比

参见:传统运行环境下的Web应用与OSGi环境下web应用分析对比

Personal tools