一、数据库结构
采用常用的用户——角色——资源结构
[img]http://www.iteye.com/upload/picture/pic/22461/8a1931c3-c81e-321a-a29d-97c5740bf335-thumb.jpg[/img]
二、在web.xml的配置
三、在applicationContext-security.xml中的配置
三、userDetailsService 代码
四、MySecureResourceFilter 代码
到这里为止,基于数据库的acegi配置就完成了,在配置的过程中我有些疑问,希望能得到高手的解答:
1、
这个标签究竟应该怎么使用?貌似是定义认证管理器的,但不知道在哪自定义认证提供者
2、
定义这个标签后,貌似
就不起作用了,debug显示加载了默认的Filter :(
采用常用的用户——角色——资源结构
[img]http://www.iteye.com/upload/picture/pic/22461/8a1931c3-c81e-321a-a29d-97c5740bf335-thumb.jpg[/img]
二、在web.xml的配置
<!-- Acegi filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
三、在applicationContext-security.xml中的配置
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd"
default-autowire="byName" default-lazy-init="true">
<b:bean id="springSecurityFilterChain"
class="org.springframework.security.util.FilterChainProxy">
<filter-chain-map path-type="ant">
<filter-chain pattern="/**"
filters="httpSessionContextIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor" />
</filter-chain-map>
</b:bean>
<!-- 这样 SecurityContext可以在web请求的开始阶段通过 SecurityContextHolder建立,然后 SecurityContext的任何修改都会在web请求结束的时候(为下一个web请求做准备)复制到 HttpSession中 -->
<b:bean id="httpSessionContextIntegrationFilter"
class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />
<!-- 用户名、密码验证 -->
<b:bean id="authenticationProcessingFilter"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
<b:property name="authenticationManager"
ref="authenticationManager" />
<b:property name="authenticationFailureUrl"
value="/login.jsp?login_error=1" />
<b:property name="defaultTargetUrl" value="/index.jsp" />
<b:property name="filterProcessesUrl"
value="/j_spring_security_check" />
</b:bean>
<!-- 用来捕捉 Spring Security异常,这样,可能返回一个HTTP错误响应,或者执行一个对应的 AuthenticationEntryPoint。 -->
<b:bean id="exceptionTranslationFilter"
class="org.springframework.security.ui.ExceptionTranslationFilter">
<b:property name="authenticationEntryPoint"
ref="authenticationProcessingFilterEntryPoint" />
<b:property name="accessDeniedHandler">
<b:bean
class="org.springframework.security.ui.AccessDeniedHandlerImpl">
<b:property name="errorPage" value="/accessDenied.jsp" />
</b:bean>
</b:property>
</b:bean>
<!-- 保护web URI -->
<b:bean id="filterInvocationInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<b:property name="authenticationManager"
ref="authenticationManager" />
<b:property name="accessDecisionManager"
ref="accessDecisionManager" />
<b:property name="objectDefinitionSource"
ref="secureResourceFilter" />
</b:bean>
<!-- 认证管理器 -->
<b:bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager">
<b:property name="providers">
<b:list>
<b:ref bean="daoAuthenticationProvider" />
</b:list>
</b:property>
<b:property name="sessionController" ref="concurrentSessionController" />
</b:bean>
<!-- 并发访问控制 -->
<b:bean id="concurrentSessionController"
class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl">
<b:property name="maximumSessions" value="1" />
<b:property name="exceptionIfMaximumExceeded" value="true"></b:property>
<b:property name="sessionRegistry">
<b:bean class="org.springframework.security.concurrent.SessionRegistryImpl"/>
</b:property>
</b:bean>
<!-- dao身份认证提供者,从数据库中获取用户信息,包括用户名和密码 -->
<b:bean id="daoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
<b:property name="userDetailsService" ref="userDetailsService" />
</b:bean>
<!--
访问决策管理器
Acegi提供三种投票通过策略的实现:
1、AffirmativeBased(至少一个投票者同意方可通过)
2、ConsensusBased(多数投票者同意方可通过)
3、UnanimousBased(所有投票者同意方可通过)
-->
<b:bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
<b:property name="allowIfAllAbstainDecisions" value="false" /><!-- 设定是否允许 “没人反对就通过” 的投票策略 -->
<b:property name="decisionVoters"><!-- 投票者 -->
<b:list>
<b:bean class="org.springframework.security.vote.RoleVoter" />
</b:list>
</b:property>
</b:bean>
<!-- 自定义的FilterInvocationDefinitionSource,在Spring Security需要对请求页面检测权限的时候调用 -->
<b:bean id="secureResourceFilter"
class="com.ywlqi.common.components.acegi.filter.MySecureResourceFilter">
<b:property name="resourceService" ref="resourceService" />
<b:property name="protectAllResource" value="true"></b:property>
<b:property name="useAntPath" value="true"></b:property>
</b:bean>
<!-- 如果用户请求受保护的HTTP请求,但是他们没有认证时被调用 -->
<b:bean id="authenticationProcessingFilterEntryPoint"
class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<b:property name="loginFormUrl" value="/login.jsp" />
<b:property name="forceHttps" value="false" />
</b:bean>
<b:bean id="loggerListener"
class="org.springframework.security.event.authentication.LoggerListener" />
<b:bean id="userDetailsService"
class="com.ywlqi.common.components.acegi.service.UserDetailServiceImpl">
<b:property name="userService" ref="userService" />
</b:bean>
<!-- 自定义的用户、角色、资源管理 -->
<b:bean id="userService" class="com.ywlqi.common.components.acegi.service.UserService" parent="baseService"/>
<b:bean id="resourceService" class="com.ywlqi.common.components.acegi.service.ResourceService" parent="baseService" />
<b:bean id="roleService" class="com.ywlqi.common.components.acegi.service.RoleService" parent="baseService" />
</b:beans>
三、userDetailsService 代码
public class UserDetailServiceImpl implements UserDetailsService{
private UserService userService;
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
// TODO Auto-generated method stub
User user = userService.getUserByName(userName);
if (user == null)
throw new UsernameNotFoundException(userName + " not found");
List<GrantedAuthority> authsList = new ArrayList<GrantedAuthority>();
Set<Role> roles = user.getRoles();
for (Role role : roles) {
authsList.add(new GrantedAuthorityImpl(role.getName()));
}
org.springframework.security.userdetails.User userdetail = new org.springframework.security.userdetails.User(
user.getName(), user.getPasswd(), user.isEnabled(), true, true, true, authsList
.toArray(new GrantedAuthority[0]));
return userdetail;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
}
四、MySecureResourceFilter 代码
public ConfigAttributeDefinition getAttributes(Object filter)
throws IllegalArgumentException {
// TODO Auto-generated method stub
FilterInvocation filterInvocation = (FilterInvocation) filter;
String url = filterInvocation.getRequestUrl();
url = preDealUrl(url, isUseAntPath(),
isConvertUrlToLowercaseBeforeComparison());
List<Resource> resourceList = resourceService.getResourcesByType("URL");
Set<Role> authorities = new HashSet<Role>();
for (Iterator iterator = resourceList.iterator(); iterator.hasNext();) {
Resource resource = (Resource) iterator.next();
if (isResourceMatch(isUseAntPath(), url, resource.getResString())) {
CollectionUtils.addAll(authorities, resource.getRoles().iterator());
}
}
ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();
StringBuffer rolesList = new StringBuffer();
for (Role role : authorities) {
rolesList.append(role.getName());
rolesList.append(",");
}
if (rolesList.length() > 0)
rolesList.replace(rolesList.length() - 1, rolesList.length() + 1, "");
configAttrEditor.setAsText(rolesList.toString());
return (ConfigAttributeDefinition) configAttrEditor.getValue();
}
到这里为止,基于数据库的acegi配置就完成了,在配置的过程中我有些疑问,希望能得到高手的解答:
1、
<authentication-manager alias="authenticationManager" />
这个标签究竟应该怎么使用?貌似是定义认证管理器的,但不知道在哪自定义认证提供者
2、
<http auto-config="true" lowercase-comparisons="true"
path-type="ant" access-decision-manager-ref="accessDecisionManager"
access-denied-page="/403.jsp" >
<concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp" default-target-url="/index.jsp" />
<logout logout-success-url="/login.jsp" />
</http>
定义这个标签后,貌似
<b:bean id="springSecurityFilterChain"
class="org.springframework.security.util.FilterChainProxy">
<filter-chain-map path-type="ant">
<filter-chain pattern="/**"
filters="httpSessionContextIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor" />
</filter-chain-map>
</b:bean>
就不起作用了,debug显示加载了默认的Filter :(
<b:bean id="filterInvocationInterceptor"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<b:property name="authenticationManager" ref="authenticationManager" />
<b:property name="accessDecisionManager" ref="accessDecisionManager" />
<b:property name="objectDefinitionSource" ref="secureResourceFilter" />
</b:bean>
的配置也不起作用了,同样是加载了默认的配置