`
xyz20003
  • 浏览: 292709 次
  • 性别: Icon_minigender_1
  • 来自: 唐山
社区版块
存档分类
最新评论

(翻译)Spring Security-2.0.x参考文档“容器适配器认证”

阅读更多
容器适配器认证
21.1. 概述

非常早期版本的Spring Security使用容器适配器进行最终用户的认证。 虽然它运行良好,但是需要很多时间来支持不同的容器版本,对于开发者来说配置时间也太长了。 因为这个原因,HTTP表单认证和HTTP基础认证方法才被开发出来,直到今天,被推荐用在几乎所有的程序中。

容器适配器让Spring Security可以将主机的最终用户程序与容器直接集成。 这种集合意味着,程序可以继续使用容易本身的认证和授权能力(比如isUserInRole()和基于表单或基本认证),虽然Spring Security提供加强的安全拦截能力(应该注意到,Spring Security也允许是用ContextHolderAwareRequestWrapper发送isUserInRole(),和简单的servlet规范兼容的方法)。

一般通过适配器进行容器和Spring Security集成。 适配器提供一个容器兼容的用户认证提供器,需要返回容器兼容的用户对象。

适配器由容器实例化,并定义在容器特定的配置文件里。 适配器将读取定义了普通的认证管理器设置的Spring的application context,就像可以用来认证请求的认证提供器一样。 application context通常叫做acegisecurity.xml,要把它放在容器指定的位置。

Spring Security现在支持Jetty, Catalina (Tomcat), JBoss 和 Resin。 其他容器的适配器也很容易编写。
21.2. 适配器认证提供器

始终是这种情况,容器适配器生成的Authentication对象还是需要在AbstractSecurityInterceptor需要处理请求的时候被AuthenticationManager认证。 AuthenticationManager需要确认适配器提供的Authentication对象是有效的,也确实被一个可信任的适配器认证过了。

适配器创建了 Authentication 对象,它是不变的,实现了AuthByAdapter接口。 这些对象保存了由适配器定义的key的散列码,。 这允许Authentication对象被AuthByAdapterProvider验证。 这个认证提供器定义如下:

<bean id="authByAdapterProvider"
        class="org.springframework.security.adapters.AuthByAdapterProvider">
<property name="key"><value>my_password</value></property>
</bean>      

这里的key必须与定义在容器特定配置文件,用来启动适配器的key相同。 这个AuthByAdapterProvider自动获得任何有效的AuthByAdapter实现,然后返回期待的key的散列值。

重申一下,这意味着适配器会在初始化认证的时候使用供应器,比如DaoAuthenticationProvider,返回一个包含key的散列值的AuthByAdapter实例,。 然后,当应用程序调用安全拦截器管理的资源时,AuthByAdapter实例,放在SecurityContextHolder里的SecurityContext,会被程序的AuthByAdapterProvider测试到。 这里不需要附加认证供应器,比如放到应用程序特定的application context里的DaoAuthenticationProvider,这是唯一的Authentication对象类型,会被从容器适配器里的程序用到的。

Classloader问题常常困扰着容器,以后会描述容器适配器的用法。 每个容器要求一个特别指定的配置。 安装教程提供在下面。 一旦安装好,请花点儿时间尝试一下例子,让你对容器适配器的配置有更多的了解。

在使用容器适配器和DaoAuthenticationProvider的时候,要确保将forcePrincipalAsString属性设置成true。
21.3. Jetty

以下代码,在Jetty 4.2.18下通过测试。

$JETTY_HOME代表你Jetty安装的根目录。

编辑 $JETTY_HOME/etc/jetty.xml 文件,在 <Configure class> 部分添加一个新的 addRealm 调用:

<Call name="addRealm">
<Arg>
  <New class="org.springframework.security.adapters.jetty.JettySpringSecurityUserRealm">
    <Arg>Spring Powered Realm</Arg>
    <Arg>my_password</Arg>
    <Arg>etc/acegisecurity.xml</Arg>
  </New>
</Arg>
</Call>

   

把 acegisecurity.xml 复制到 $JETTY_HOME/etc目录下。

把下面的文件复制到 $JETTY_HOME/ext目录下:

    *

      aopalliance.jar
    *

      commons-logging.jar
    *

      spring.jar
    *

      acegi-security-jetty-XX.jar
    *

      commons-codec.jar
    *

      burlap.jar
    *

      hessian.jar

上面那些JAR文件(或者是acegi-security-XX.jar)都不能放在你程序的WEB-INF/lib目录下。 你的web.xml里设置的realm名字是与Jetty对应的。 web.xml必须使用与你的jetty.xml里相同的<realm-name>(像上面的例子里,"Spring Powered Realm")。
21.4. JBoss

下面的代码在JBoss 3.2.6下通过了测试。

$JBOSS_HOME代表你JBoss安装的根目录。

有两个不同方法,把spring环境集成到Jboss里。

第一种方法是,修改你的 $JBOSS_HOME/server/your_config/conf/login-config.xml 文件,这样它就在<Policy>部分包含了新的入口:

<application-policy name = "SpringPoweredRealm">
<authentication>
  <login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule"
        flag = "required">
    <module-option name = "appContextLocation">acegisecurity.xml</module-option>
    <module-option name = "key">my_password</module-option>
</login-module>
</authentication>
</application-policy>

   

把 acegisecurity.xml 复制到 $JBOSS_HOME/server/your_config/conf目录下。

在配置文件 acegisecurity.xml里包含了spring环境的定义,包含了所有认证管理的bean。 我们必须注意,SecurityContext会在每次请求时被创建销毁,所以登录操作会造成很大的资源消耗。 可选的第二个方法通过org.springframework.beans.factory.access.SingletonBeanFactoryLocator使用Spring单例。 需要的配置方法如下:

<application-policy name = "SpringPoweredRealm">
<authentication>
  <login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule"
        flag = "required">
    <module-option name = "singletonId">springRealm</module-option>
    <module-option name = "key">my_password</module-option>
    <module-option name = "authenticationManager">authenticationManager</module-option>
</login-module>
</authentication>
</application-policy>

   

上面的代码片段, authenticationManager是一个助手属性,定义成期望的AuthenticationManager的名字,在IoC容器里有多个定义的时候可以用到。 这个singletonId属性引用了定义在beanRefFactory.xml中的一个bean。 这个文件需要放在JBoss的classpath中,包括$JBOSS_HOME/server/your_config/conf。 这个beanRefFactory.xml包含了下面的声明:

<beans>
<bean id="springRealm" singleton="true" lazy-init="true" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
  <list>
    <value>acegisecurity.xml</value>
  </list>
</constructor-arg>
</bean>
</beans>

   

最后,无论使用了哪种配置方法,你需要把下面的文件复制到 $JBOSS_HOME/server/your_config/lib目录下:

    *

      aopalliance.jar
    *

      spring.jar
    *

      acegi-security-jboss-XX.jar
    *

      commons-codec.jar
    *

      burlap.jar
    *

      hessian.jar

上面那些JAR文件(或者是acegi-security-XX.jar)都不能放在你程序的WEB-INF/lib目录下。 你的web.xml里设置的realm名字是与JBoss对应的。 然而,你web应用的WEB-INF/jboss-web.xml里的<security-domain>应该与你的login-config.xml中的内容一样。 比如,你的jboss-web.xml看起来应该是这样:
21.5. Resin

下面的代码在Resin 3.0.6下通过测试。

$RESIN_HOME代表你Resin安装的根目录。

Resin提供了好几种方法实现容器适配器。 在下面的教程里,我们使用了尽量与其他容器适配器一致的配置。 这会让Resin用户更容易发布同样的程序,确保配置正确。 开发者对Resin感到舒服,自然可以使用它的方法,打包JAR同web程序自己,和/或支持单点登录。

把下面的文件复制到 $RESIN_HOME/lib目录下:

    *

      aopalliance.jar
    *

      commons-logging.jar
    *

      spring.jar
    *

      acegi-security-resin-XX.jar
    *

      commons-codec.jar
    *

      burlap.jar
    *

      hessian.jar

与其他容器适配器使用的,容器范围的 acegisecurity.xml文件不同,每个Resin web程序会包含自己的WEB-INF/resin-acegisecurity.xml文件。 每个web应用会包含一个resin-web.xml文件,Resin用它来启动容器适配器:

<web-app>
<authenticator>
<type>org.springframework.security.adapters.resin.ResinAcegiAuthenticator</type>
<init>
  <app-context-location>WEB-INF/resin-acegisecurity.xml</app-context-location>
  <key>my_password</key>
</init>
</authenticator>
</web-app>

   

像上面提供的基本配置那样,上面那些JAR文件(或者是acegi-security-XX.jar)都不能放在你程序的WEB-INF/lib目录下。 你的web.xml里设置的realm名字是与Resin无关的,认证的类根据<authenticator>设置的。
21.6. Tomcat

下面的代码在Jakarta Tomcat 4.1.30 和 5.0.19通过的了测试。

$CATALINA_HOME代表你的 Catalina (Tomcat) 安装根目录。

编辑你的 $CATALINA_HOME/conf/server.xml 文件,让 <Engine> 部分只包含一个活动的 <Realm> 入口。一个 realm入口的例子如下:

      <Realm
        className="org.springframework.security.adapters.catalina.CatalinaSpringSecurityUserRealm"
        appContextLocation="conf/acegisecurity.xml"
         key="my_password" />

确认从你的 <Engine>部分删除了其他的 <Realm> 入口。

把 acegisecurity.xml 复制到$CATALINA_HOME/conf目录下。

把 spring-security-catalina-XX.jar 复制到$CATALINA_HOME/server/lib 目录下。

吧下面的文件复制到 $CATALINA_HOME/common/lib目录下:

    *

      aopalliance.jar
    *

      spring.jar
    *

      commons-codec.jar
    *

      burlap.jar
    *

      hessian.jar

上面那些JAR文件(或者是acegi-security-XX.jar)都不能放在你程序的WEB-INF/lib目录下。 你的web.xml里设置的realm名字是与Catalina无关的。

我们收到了在Mac OS X下使用这个容器适配器的问题报告。需要使用下面的脚本:

#!/bin/sh
export CATALINA_HOME="/Library/Tomcat"
export JAVA_HOME="/Library/Java/Home"
cd /
$CATALINA_HOME/bin/startup.sh

最后,重启tomcat。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics