OSGi环境下结合Spring对Acegi的集成
From Tuscany中文社区
目录 |
[编辑] 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中被实例化。
在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服务器上。
[编辑] 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;
}
}

