附录 B. 常见问题解答

B.1.

Q: 如何获得源代码

A: 在SpringSecurity的发布包中的dist目录下,包含很多“.jar”文件,名称中包含“sources”的文件中就是源文件了,比如:可以在spring-security-core-3.1.3.RELEASE-sources.jar中找到core模块的所有文件。

B.2.

Q: 为何登录时出现There is no Action mapped for namespace / and action name j_spring_security_check.

A: 这是因为登陆所发送的请求先被struts2的过滤器拦截了,为了试登陆请求可以被Spring Security正常处理,需要在web.xml中将Spring Security的过滤器放在struts2之前。

B.3.

Q: 用户登陆之后没有进入设置的default-target-url页面。

A: Spring Security登陆成功后的策略是,先判断用户登录前是否尝试访问过受保护的页面,如果有,则跳转到用户登录前访问的受保护页面,否则跳转到default-target-url。如果希望登陆后一直跳转到default-target-url,可以使用always-use-default-target="true"。

B.4.

Q: 如何实现国际化。

A: 在xml中添加如下配置:

<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <beans:property name="basename" value="org/springframework/security/messages" />
</beans:bean>
            

B.5.

Q: 如何监听Spring Security的事件日志。

A: 在xml中添加如下配置:

<beans:bean class="org.springframework.security.event.authentication.LoggerListener"/>

<beans:bean class="org.springframework.security.event.authorization.LoggerListener"/>
            

B.6.

Q: 如何启用group。

A: 设置enableGroups="true"才能在JdbcDaoImpl中启用group,默认是禁用的。

namespace中没有支持这个参数,如果想使用group,只要设置group-authorities-by-username-query这个属性,就会自动打开enableGroups。

B.7.

Q: 如何判断用户是否登录到系统中。

A: 有三种方式判断用户是否登录进了系统。

  • 如果没有使用anonymous,SecurityContextHolder.getContext().getAuthenticaiton() == null时用户就没有登录。

  • 如果使用了anonymous,SecurityContextHolder.getContext().getAuthentication() instanceof AnonymousAuthenticationToken时用户就没有登录。

  • 如果可以获得HttpSession,当session.getAttribute(HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY) == null时,用户就没有登录。

B.8.

Q: 为什么在过滤器链里多加了一个FilterSecurityInterceptor,原来的FilterSecurityInterceptor就不控制请求了。

A: 因为FilterSecurityInterceptor会向request中写入一个标记,用于标记是否已经控制了当前请求,这样可以避免对同一个请求多次处理。因为前一个FilterSecurityInterceptor会在request中做一个标记,这就会导致第二个FilterSecurityInterceptor不会再次执行了。

B.9.

Q: 如何记录登录ip和登录时间。

A: 参考第 43 章 自定义过滤器中的内容,自定义一个过滤器,将用户登录ip和登录时间记录到session中。

B.10.

Q: 如何在新建用户时,使用saltValue对密码进行配置?

A: 可以参考第 56 章 最简控制台中的第四节 添加用户,使用String encodedPassword = passwordEncoder.encodePassword(password, username);获得加密后的密码。

B.11.

Q: 如何让没配置的资源也要通过认证才能访问?

A: 需要为AccessDecisionManager设置allowIfAllAbstainDecisions="false",这样当遇到没有显式定义的被保护资源都保护起来,实际上是都投反对票,所以那些没定义的资源谁也无法访问。

B.12.

Q: Spring Security 2与Acegi相比有哪些功能提升?

  • 简化的namespace配置语法

  • 集成OpenID

  • 支持NTLM

  • 支持JSR250

  • 支持AspectJ语法

  • 提升ACL的性能

  • 支持RESTful系统

  • 添加对用户组的支持

  • 加强了基于数据库的remember-me实现

  • 支持portlet

  • 支持其他语言

  • 提供了更多的代码加强,文档和新实例

  • 提供对spring web flow 2.0的支持

  • 支持在Spring IDE下进行可视化配置

  • 加强了对Spring Web Service的支持

  • 更新了对CAS的支持,现在支持CAS3

B.13.

Q: 不要过滤图片等静态资源。

<http security="none" pattern="/favicon.ico"/>
<http security="none" pattern="/**/*.jpg"/>
<http security="none" pattern="/**/*.png"/>
<http security="none" pattern="/**/*.gif"/>
<http security="none" pattern="/**/*.css"/>
<http security="none" pattern="/**/*.js"/>