<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd ">
<!--
<http>:
配置http元素时, spring创建一个名为"springSecurityFilterChain"的FilterChainProxy类型bean, 并且
在FilterChainProxy内部使用http元素中的配置来创建一个filter chain; 从spring security 3.1开始, 额外的
http元素可以用来增加额外的filter chain, 一个应用可以配置多个http, 每个http元素生成一个filter chain,
这些filter chain按声明的顺序注入FilterChainProxy中; 在处理外部request时, 按声明的顺序使用FilterChainProxy中的
filter chain 对request进行验证处理, 直到认证通过或者认证失败抛出异常.
在filter chain中, 一些核心的filters总是由spring自动创建, 其他filter的创建则依赖于http的属性和子元素的配置,
它们都将在filter stack中创建, filter stack中标准filter的位置总是固定的, 所有需要注入AuthenticationManager的filter
都会自动注入 一个由 namespace 创建的AuthenticationManager内部实例.
每个http namespace block 总是会自动创建核心的SecurityContextPersistenceFilter, ExceptionTranslationFilter
FilterSecurityInterceptor; 它们的位置是固定的, 并且不能被取代.
<http> Attributes: http元素中的属性用于控制核心filter的一些属性.
access-decision-manager-ref: 可选的属性, 配置AccessDecisionManager, 用来进行http request授权; 缺省
使用AffirmativeBased实现和RoleVoter, AuthenticatedVoter投票器.
authentication-manager-ref: 配置当前http元素的filter chain使用的AuthenticationManager.
auto-config: 设置为true时自动注册login-form, basic authentication 和 logout服务; 缺省是false, 不推荐使用该配置,
应该使用明确的相应元素进行配置,以免造成混乱.
create-session: 缺省是ifRequired, 只在需要时创建session; always表示如果不存在session,spring 会主动创建;
never表示从不创建,但会使用应用自己创建的session; stateless表示spring 从不创建而且session会忽略权限验证.
disable-url-rewriting: 缺省为true, 阻止在返回客户端的URL上添加sessionID, 客户端必须开启支持cookie.
entry-point-ref: 通常被设置为AuthenticationEntryPoint, 用来指定authentication的入口点, 改写该属性以使用自定义的入口.
once-per-request: 配置FilterSecurityInterceptor的observeOncePerRequest属性, 缺省是true.
pattern: 当前http元素的对应filter chain需要处理的request url, 依赖于 request-matcher的配置; 如果没有配置, 所有的request都将匹配,
最具体的pattern 应该放置在最前面.
request-matcher: FilterChainProxy中当前http元素对应的filter chain 和子元素intercept-url 创建的bean使用的RequestMatcher,
用来匹配request; 选项有ant, regex和ciregex(大小写不敏感), 分别使用AntPathRequestMatcher, RegexRequestMatcher, 每个
intercept-url都可以使用自己的pattern和method属性创建独立的RequestMatcher实例.
realm: basic authentication使用的 realm 名称, 必须与BasicAuthenticationEntryPoint的realmName 属性一致.
security: 设置为none, 映射一个空的filter chain, 表示spring security对pattern匹配的request url失效.
security-context-repository-ref: 注入自定义的SecurityContextRepository 到 SecurityContextPersistenceFilter.
servlet-api-provision: 缺省是true, 添加SecurityContextHolderAwareRequestFilter 到filter stack中以支持相应版本的
HttpServletRequest安全接口, 如isUserInRole() 和 getPrincipal().
use-expressions: 缺省是true, 激活时可以在access属性中使用表达式配置 EL-expressions.
-->
<!-- http 子元素 -->
<!--
<access-denied-handler>: 配置ExceptionTranslationFilter使用的AccessDeniedHandler和errorPage属性.
error-page: 当已验证的用户请求一个没有访问权限的资源时,redirect to 访问拒绝提示页面.
ref: 指向一个AccessDeniedHandler 类型的bean.
-->
<!--
<anonymous>: 添加一个AnonymousAuthenticationFilter到 filter stack中, 并将AnonymousAuthenticationProvider
注入ProviderManager的AuthenticationProvider列表中, 以支持对AnonymousAuthenticationToken的认证,
http元素的使用默认就会启用对匿名认证的支持, 使用access属性值 IS_AUTHENTICATED_ANONYMOUSLY表示需要匿名认证.
AnonymousAuthenticationToken将作为一个Authentication的实例存放在SecurityContextHolder中; filter chain运行到
AnonymousAuthenticationFilter时, 如果SecurityContextHolder中持有的Authentication还是空的, 则AnonymousAuthenticationFilter
将创建一个AnonymousAuthenticationToken并存放在SecurityContextHolder中. AnonymousAuthenticationToken的认证是
在AbstractSecurityInterceptor中的beforeInvocation()方法中进行的.
enabled: 随着namespace http元素的创建, anonymous authentication的能力自动激活,如果想要关闭anonymous验证, 可以使用这个属性.
granted-authority: 缺省是ROLE_ANONYMOUS, 设置赋予anonymous request的授权,用于随后的authorization decisions.
username: 缺省是anonymousUser, 设置赋予anonymous request的principal用户名, 一般用于日志和核查.
key: 在AnonymousAuthenticationProvider和AnonymousAuthenticationFilter之间共享, 它们必须保持一致, AnonymousAuthenticationProvider
将使用本身拥有的key与传入的AnonymousAuthenticationToken的key作比较, 相同则认为可以进行认证, 否则将抛出异常BadCredentialsException.
-->
<!--
<csrf>: 为应用增加Cross Site Request Forger (CSRF) 保护.
disabled: 缺省是false(打开CSRF), 可选的属性, 用于关闭CSRF保护.
token-repository-ref: 设置CsrfTokenRepository, 缺省是HttpSessionCsrfTokenRepository.
request-matcher-ref: 设置RequestMatcher用于决定是否对当前request进行CSRF保护, 缺省是除了"GET", "TRACE", "HEAD", "OPTIONS"的
任何http method进行保护.
-->
<!--
<custom-filter>: 用于增加一个filter到filter chain中, 该元素不会创建任何bean, 它只用于选择application context 中定义的javax.servlet.Filter
类型的bean, 并把它放置在spring security维护的filter chain的特定位置上.
before: custom-filter 在 filter chain中的位置紧挨在before指定的标准filter之前.
position: custom-filter 在filter chain中的精确位置, 用于替换标准的filter.
after: custom-filter 在 filter chain中的位置紧挨在after指定的标准filter之后, 该特性只被高级开发者使用.
ref: 指向Filter类型的spring bean.
-->
<!--
<form-login>: 添加UsernamePasswordAuthenticationFilter 到filter stack中, 并为应用增加LoginUrlAuthenticationEntryPoint 用于提供验证入口,
该入口总是优先于由namespace创建的入口, 如果不提供任何属性, 会自动为/login 请求生成一个login page.
default-target-url: 缺省是根目录"/", 对应UsernamePasswordAuthenticationFilter的defaultTargetUrl属性, 通常设置为home page.
always-use-default-target: 缺省是false, 设置为true表示通过验证后总是转向default-target-url指定的页面, 对应UsernamePasswordAuthenticationFilter
的alwaysUseDefaultTargetUrl属性.
authentication-details-source-ref: 指向AuthenticationDetailsSource.
authentication-failure-handler-ref: 可以作为authentication-failure-url的替代, 提供验证失败后的导航流程的完全控制, 指向AuthenticationFailureHandler类型bean.
authentication-failure-url: 缺省是"/login?error", 定义验证失败时转向的url, 对应UsernamePasswordAuthenticationFilter的authenticationFailureUrl属性.
authentication-success-handler-ref: 可以作为default-target-url 和 always-use-default-target的替代, 提供验证成功后的导航流程的完全控制,
指向AuthenticationSuccessHandler 类型bean, 缺省使用SavedRequestAwareAuthenticationSuccessHandler并注入 default-target-url.
login-page: 缺省是"/login", 用于呈现登录页面的url, 对应 LoginUrlAuthenticationEntryPoint的 loginFormUrl属性.
login-processing-url: 缺省是"/login", 用于处理登录请求, 对应 UsernamePasswordAuthenticationFilter的 filterProcessesUrl属性.
password-parameter: 缺省"password", request parameter 的参数名, 表示password.
username-parameter: 缺省"username", request parameter 的参数名, 表示username.
-->
<!--
<http-basic>: 添加BasicAuthenticationFilter 和 BasicAuthenticationEntryPoint配置.
authentication-details-source-ref: 指向AuthenticationDetailsSource类型bean, 用于authentication filter.
entry-point-ref: 指向AuthenticationEntryPoint类型bean, 用于BasicAuthenticationFilter.
-->
<!--
<intercept-url>: 定义应用关注的URL patterns 并配置如何处理这些url, 它被用来构建FilterSecurityInterceptor使用的FilterInvocationSecurityMetadataSource,
也负责配置ChannelProcessingFilter, 如果特定的url需要使用https访问.
the most specific matches patterns should come first and the most general should come last.
access: 使用分号分隔的security属性列表(rolename), 保存在FilterInvocationSecurityMetadataSource 中.
method: HTTP Method, 不指定时匹配任何Method, 结合pattern对request进行匹配, 优先匹配Method.
pattern: 定义url path, 依赖于http元素的request-matcher 属性, 缺省使用ant 路径语法.
requires-channel: http, https 和any. 使用该属性时, ChannelProcessingFilter 被加入filter stack, 它的依赖属性也会被加入application Context.
-->
<!--
<logout>: 增加LogoutFilter 到filter stack, LogoutFilter使用SecurityContextLogoutHandler和CookieClearingLogoutHandler进行logout相应的配置处理.
delete-cookies: logout 时要删除的cookie 名称列表, 用分号分隔, 对应CookieClearingLogoutHandler的cookiesToClear属性.
invalidate-session: 缺省是true, 表示logout时session.invalidate(), 对应SecurityContextLogoutHandler的invalidateHttpSession属性.
logout-success-url: 缺省是<form-login-login-page>/?logout (比如 /login?logout), logout成功后转向的页面, 设置该属性会将
SimpleRedirectInvalidSessionStrategy 注入SessionManagementFilter中, 当一个invalid session ID 被提交时, SimpleRedirectInvalidSessionStrategy
会被调用, 并将request redirect to 配置的 URL.
logout-url: 缺省是"/logout", 用于处理logout请求.
success-handler-ref: 指向LogoutSuccessHandler 类型bean, 用于控制logout后的导航.
-->
<!--
<port-mappings>: 缺省PortMapperImpl 实例被加入配置中, 用来重定向http和https URLs. 每个<port-mapping> 子元素定义一对http:https端口.
缺省的映射是80:43 和 8080:8443.
<port-mapping>: http和https属性用于设置相应的端口.
-->
<!--
<remember-me>: 添加RememberMeAuthenticationFilter 到filter stack中, 应该被配置为TokenBasedRememberMeServices, PersistentTokenBasedRememberMeServices
或者一个自定义的RememberMeServices 实现.
authentication-success-handler-ref: 如果需要自定义的导航, 设置AuthenticationSuccessHandler 类型bean, 对应RememberMeAuthenticationFilter的
authenticationSuccessHandler 属性.
data-source-ref: 指向DataSource bean, 如果配置该属性, 则使用PersistentTokenBasedRememberMeServices 并自动注入JdbcTokenRepositoryImpl.
remember-me-parameter: 缺省是"remember-me", request parameter的参数名, 对应AbstractRememberMeServices的parameter属性.
remember-me-cookie: 缺省是"remember-me", 设置存储remember-me token的cookie名称, 对应AbstractRememberMeServices的cookieName属性.
key: 必须被设置成唯一的值, 如果没有设置, 将使用随机产生的安全值.
services-alias: 设置内部使用的RememberMeServices 的别名, 以供application Context中的其他bean使用.
services-ref: 指向一个RememberMeServices 实现的id, 如果使用了logout filter, 还需要实现LogoutHandler.
token-repository-ref: 配置PersistentTokenBasedRememberMeServices使用的PersistentTokenRepository, 也可以使用自定义的PersistentTokenRepository 实现.
token-validity-seconds: 缺省是2周, 设置remember-me cookie的有效时间, 对应AbstractRememberMeServices的tokenValiditySeconds属性.
use-secure-cookie: 缺省是true, 推荐remember-me cookie应该通过https提交, 对应AbstractRememberMeServices的useSecureCookie 属性.
user-service-ref: RememberMeServices 实现 需要访问UserDetailsService, 如果application context中只有一个配置的bean, namespace创建时会自动
选择该bean, 如果定义了多个UserDetailsService, 则使用该属性明确的指定一个bean的id.
-->
<!--
<request-cache>: ExceptionTranslationFilter在调用AuthenticationEntryPoint之前用来保存request 信息的RequestCache, 为了在验证成功后重新转向该request.
ref: 指向RequestCache类型bean.
-->
<!--
<session-management>: session管理的功能是通过添加 SessionManagementFilter 到filter stack中实现的.
invalid-session-url: 设置该属性会将 SimpleRedirectInvalidSessionStrategy 注入SessionManagementFilter中, 当一个invalid session ID 被提交时,
SimpleRedirectInvalidSessionStrategy会 被调用, 并将request redirect to 配置的 URL.
session-authentication-error-url: 设置当SessionAuthenticationStrategy 抛出异常时的错误页面, 如果没有设置, 返回unauthorized (401) error code
到客户端, 该属性不适用在form-login验证期间遇到的错误, form-login优先使用自己的authentication-failure-url.
session-authentication-strategy-ref: 注入SessionManagementFilter使用 的SessionAuthenticationStrategy.
session-fixation-protection: 设置session固态攻击保护策略, 当session-fixation-protection触发时会导致在application context中传播
SessionFixationProtectionEvent事件, 同时会导致javax.servlet.http.HttpSessionIdListener 通知.
none:不做任何保护,保留原始的session
newSession:创建新的session, 不复制session数据(spring security相关的数据会被复制)
migrateSession:创建新的session, 并复制所有的session数据,servlet3.0容器及更低版本中的默认选项
changeSessionId:不创建新的session, 使用容器提供的session固态攻击保护策略(HttpServletRequest#changeSessionId()), servlet3.1版本容器中的默认选项,
在servlet3.1以下版本的容器中指定该选项会抛出异常.
<concurrency-control>: 增加session并发管理, 限制一个用户拥有的活跃session数量, ConcurrentSessionFilter 加入filter stack, SessionManagementFilter
会使用ConcurrentSessionControlAuthenticationStrategy, 如果已经定义了form-login 元素, ConcurrentSessionControlAuthenticationStrategy也会被注入
创建的authentication filter中, ConcurrentSessionControlAuthenticationStrategy会创建SessionRegistry (SessionRegistryImpl) 实例.
error-if-maximum-exceeded: 缺省为false, 会expired最初的SessionInformation, 设置为true时, 当尝试超出设定的session限制时,抛出SessionAuthenticationException.
expired-url: 当error-if-maximum-exceeded为false时,应该设置该属性, 被并发控制器标记为expired的session应该被重定向到该url, 如果不设置,
则直接将expired提示信息写入response.
max-sessions: -1表示不限制, 对应ConcurrentSessionControlAuthenticationStrategy的maximumSessions 属性.
session-registry-alias: 为内部的SessionRegistry创建别名, 可以在application Context中的其他bean使用,通常作为管理接口.
session-registry-ref: 设置自定义的SessionRegistry 实现, 其他并发控制的bean会直接使用该属性指定的bean.
-->
<!-- **代表可以跨越目录, *不可以跨越目录. -->
<security:http pattern="/resources/**" security="none" />
<security:http pattern="/*.html" security="none" />
<!-- 默认auto-config="false",设置auto-config="true"时,自动注册form-login、basic authentication、logout。
默认use-expressions="true" 需要使用表达式hasRole('ROLE_USER') -->
<security:http use-expressions="false">
<!-- 设置没有访问权限时转向的提示页面 -->
<security:access-denied-handler error-page="/accessDenied.html" />
<!-- 设置匿名用户可以访问的url -->
<security:intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- 设置相应角色可以访问的url -->
<security:intercept-url pattern="/security/**" access="ROLE_ADMIN" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
<!-- 设置自定义的登录页面和登录后的缺省home主页
login-page不设置时,spring自动使用"/login"。
default-target-url不设置时,登录成功后转向登录之前的请求url,如果没有则指向根目录"/"。
always-use-default-target="true"登录成功后始终转向default-target-url。
authentication-failure-url设置登录失败时转向的页面,如果不设置spring会自动转向"/login?error"。 -->
<security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=1"
default-target-url="/" always-use-default-target="true" />
<!-- 默认invalidate-session="true"在logout时使session失效,logout-success-url设置logout成功后转向的页面-->
<security:logout logout-success-url="/logout.html" invalidate-session="true"/>
<!-- data-source-ref="dataSource"使用数据库持久化remember me标记 -->
<security:remember-me data-source-ref="dataSource" user-service-ref="userDetailsService" />
<!-- <security:session-management session-authentication-strategy-ref="sessionAuthenticationStrategy"/> -->
<security:session-management invalid-session-url="/invalidSession.html">
<security:concurrency-control max-sessions="1" session-registry-alias="sessionRegistry" />
</security:session-management>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailsService">
<security:password-encoder ref="bcryptEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<bean id="bcryptEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<!-- 配置UserDetailsService实现,可以使用自定义的UserDetailsService实现获得数据库的用户信息UserDetails -->
<bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource" />
<property name="usersByUsernameQuery"
value="SELECT username, password, enable FROM user WHERE username=?" />
<property name="authoritiesByUsernameQuery"
value="SELECT u.username as username, r.rolename as rolename
FROM user u
JOIN user_group ug ON u.id=ug.user_id
JOIN groups g ON ug.group_id=g.id
JOIN group_role gr ON g.id=gr.group_id
JOIN role r ON gr.role_id=r.id
WHERE u.username=?" />
</bean>
</beans>