- 本文章摘编、转载需要注明来源 http://write.blog.csdn.net/postedit/8575062
spring security3中的权限管理虽然有文件可配置,但是很多时候我们是需要数据库的支持,下面我演示下如何配置自定义权限管理,这个时候需要重新实现下面的类,
该文章适合对spring security3 有一定理解的人员
AccessDecisionManager是验证资源跟角色之间的关系,由于我个人不太喜欢用标签化,因为感觉灵活性不够好,所以我统一是用bean方式,至于用bean来描述是需要对security的
过滤链流程和各个属性依赖关系比较熟悉的了解才可以配置成功,这样灵活性大大加强
-
-
-
-
-
-
-
- public class AccessDecisionManagerImpl implements AccessDecisionManager {
-
- public void decide(Authentication authentication, Object object,
- Collection<ConfigAttribute> attributes)
- throws AccessDeniedException, InsufficientAuthenticationException {
- if (null == attributes)
- return;
- for (ConfigAttribute attribute : attributes) {
- String needRole = ((SecurityConfig) attribute).getAttribute();
-
- for (GrantedAuthority grantedAuthority : authentication
- .getAuthorities()) {
- if (needRole.equals(grantedAuthority.getAuthority()))
- return;
- }
- }
- throw new AccessDeniedException("权限不足!");
- }
-
- public boolean supports(ConfigAttribute attribute) {
- return true;
- }
-
- public boolean supports(Class<?> clazz) {
- return true;
- }
- }
SecurityMetadataSource是角色跟资源加载器,项目启动的时候会先执行资源跟角色关联加载提供给security以便认证
FilterSecurityInterceptor是资源访问第一个需要经过的过滤器,这个类我们还是不需要重写了,直接使用spring security提供的比较
具体路径org.springframework.security.web.access.intercept.FilterSecurityInterceptor
UserDetailsService这个类security的form表单登录处理
-
-
-
-
-
-
-
- public class UserDetailsServiceImpl implements UserDetailsService {
-
- private UserService userService;
- private RoleService roleService;
-
- public UserService getUserService() {
- return userService;
- }
-
- @Resource
- public void setUserService(UserService userService) {
- this.userService = userService;
- }
-
- public RoleService getRoleService() {
- return roleService;
- }
-
- @Resource
- public void setRoleService(RoleService roleService) {
- this.roleService = roleService;
- }
-
- public UserDetails loadUserByUsername(String username)
- throws UsernameNotFoundException {
-
-
- List<User> users = this.userService.findByUserName(username);
-
- if (null == users || users.isEmpty())
- throw new UsernameNotFoundException("用户/密码错误,请重新输入!");
-
- User user = users.get(0);
- List<Role> roles = this.roleService.findByUserId(user.getId());
- if (null == roles || roles.isEmpty())
- throw new UsernameNotFoundException("权限不足!");
-
- Collection<GrantedAuthority> gaRoles = new ArrayList<GrantedAuthority>();
- for (Role role : roles) {
- gaRoles.add(new SimpleGrantedAuthority(role.getName()));
- }
- user.setAuthorities(gaRoles);
- return user;
- }
-
- }
三个类都准备好了现在去配置xml文件,先声明三个类的bean
- <!-- 自定义UserDetailsService认证 -->
- <bean id="userDetailsService"
- class="com.shadow.security.service.UserDetailsServiceImpl" />
-
- <!-- 自定义资源权限关系认证 -->
- <bean id="accessDecisionManager"
- class="com.shadow.security.service.AccessDecisionManagerImpl" />
-
- <!-- 自定义资源权限关系集合 -->
- <bean id="securityMetadataSource"
- class="com.shadow.security.service.SecurityMetadataSourceExtendImpl">
- <property name="matcher" value="ant" />
- </bean>
然后配置filterSecurityInterceptor,我们不再用security提供的实现类,而是使用我们刚刚写的实现类
- <!-- 自定义认证管理,资源,权限 -->
- <bean id="filterSecurityInterceptor"
- class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
- <property name="authenticationManager"
- ref="authenticationManager" />
- <property name="accessDecisionManager"
- ref="accessDecisionManager" />
- <property name="securityMetadataSource"
- ref="securityMetadataSource" />
- </bean>
至于authenticationManager的注入如下(rememberMeAuthenticationProvider可不注入,这个东西是记住密码功能需要用到的玩意)
- <!-- 认证管理器 -->
- <bean id="authenticationManager"
- class="org.springframework.security.authentication.ProviderManager">
- <property name="providers">
- <list>
- <ref bean="daoAuthenticationProvider" />
- <ref bean="rememberMeAuthenticationProvider" />
- </list>
- </property>
- </bean>
-
- <!-- 登录认证处理 -->
- <bean id="daoAuthenticationProvider"
- class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
- <property name="hideUserNotFoundExceptions" value="false"/>
- <property name="userDetailsService" ref="userDetailsService" />
- <property name="passwordEncoder" ref="passwordEncoder" />
- <property name="saltSource" ref="saltSource" />
- </bean>
-
- <!-- 加密方式 -->
- <bean id="passwordEncoder"
- class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
-
- <!-- 配置加密盐值 -->
- <bean id="saltSource"
- class="org.springframework.security.authentication.dao.ReflectionSaltSource">
- <property name="userPropertyToUse" value="username" />
- </bean>
然后配置我们的过滤链
- <!-- 自定义SPRING SECURITY过滤链 -->
- <bean id="securityFilterChainProxy"
- class="org.springframework.security.web.FilterChainProxy">
- <constructor-arg>
- <list>
- <security:filter-chain pattern="/services/**"
- filters="none" />
- <security:filter-chain pattern="/test*" filters="none" />
- <security:filter-chain pattern="/**"
- filters="concurrentSessionFilter,securityContextPersistenceFilter,logoutFilter,usernamePasswordAuthenticationFilter,rememberMeAuthenticationFilter,sessionManagementFilter,anonymousAuthFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
- </list>
- </constructor-arg>
- </bean>