标签:
RBAC:基于角色的访问控制(Role-Based Access Control)
先在web.xml 中配置一个过滤器(必须在Struts的过滤器之前)
- <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>
然后就是编写Spring安全的配置文件applicationContext-security.xml并配置到Spring解析的路径下
Spring Security主要做两件事,一件是认证,一件是授权。
认证
当用户访问受保护的信息却没有登录获得认证时,框架会自动将请求跳转到登录页面
在http标签中的
- <form-login login-page="/page/login.jsp" />
配置。且该登录页面必须是不被拦截的。故要配置上
- <intercept-url pattern="/page/login.jsp" filters="none" />
Web项目的认证如果在HTTP标签中配置了auto-config="true",框架就会自动的配置多8?个拦截器。
默认表单登录认证的是FORM_LOGIN_FILTER拦截器,我们可以直接写自定义的UserDetailsService,在这个类中实现方法
UserDetails loadUserByUsername(String username),从数据库获取用户信息,以及其拥有的角色。
- @Service("myUserDetailsService")
- public class MyUserDetailsServiceImpl extends BaseService implements UserDetailsService {
- @Resource
- private UserDao userDao;
-
-
- public UserDetails loadUserByUsername(String username)
- throws UsernameNotFoundException, DataAccessException {
-
- User user = userDao.getUserByUsername(username);
- List<Role> roles = user.getRoles();
- Collection<GrantedAuthority> authorities = new LinkedList<GrantedAuthority>();
-
- for (Role role : roles) {
- authorities.add(new GrantedAuthorityImpl(role.getCode()));
- }
-
- UserDetails userDetails = new org.springframework.security.core.userdetails.User(username,user.getPassword(),Constants.STATE_VALID.equals(user.getState()),true,true,true,authorities);
-
- return userDetails;
- }
-
-
- }
配置在
- <authentication-manager alias="myAuthenticationManager">
- <authentication-provider user-service-ref="myUserDetailsService">
- <password-encoder hash="md5" />
- </authentication-provider>
- </authentication-manager>
如果需要在登录的时候,在HTTP SESSION中配置做些操作的。就得配置自定义的FORM_LOGIN_FILTER了
在HTTP标签中加入
- <custom-filter ref="loginFilter" before="FORM_LOGIN_FILTER" />
并配置
- <beans:bean id="securityFilter"
- class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
- <beans:property name="authenticationManager" ref="myAuthenticationManager" />
- <beans:property name="accessDecisionManager"
- ref="affirmativeBasedAccessDecisionManager" />
- <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource"/>
- </beans:bean>
MyUsernamePasswordAuthenticationFilter 类是这么写的
- public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{
- public static final String USERNAME = "username";
- public static final String PASSWORD = "password";
-
- @Resource
- private LoginService loginService;
- private UserLoginFormBean userLoginFormBean = new UserLoginFormBean();
-
- @Resource
- private LogService logService;
-
-
-
- @Override
- public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
- String username = obtainUsername(request);
- String password = obtainPassword(request);
-
- HttpSession session = request.getSession();
-
- userLoginFormBean.setUsername(obtainUsername(request));
- userLoginFormBean.setPassword(obtainPassword(request));
-
- User user = loginService.login(userLoginFormBean);
- session.setAttribute(Constants.SESSION_USER, user);
-
-
- Log log = new Log(user,getIpAddr(request),"用户登录", null);
- logService.add(log);
-
- UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
-
- setDetails(request, authRequest);
-
-
- return this.getAuthenticationManager().authenticate(authRequest);
- }
-
-
-
- }
getAuthenticationManager().authenticate(authRequest)是为了让UserDetailService提供Detailed的信息并认证
授权
在授权时,系统默认通过FILTER_SECURITY_INTERCEPTOR认证。
如需自定义授权拦截器,我们在HTTP中在默认授权拦截器前配置了自定义的拦截器
- <custom-filter ref="securityFilter" before="FILTER_SECURITY_INTERCEPTOR" />
本平台采用基于请求URL地址的验证方式
securityFilter的配置如下
- <beans:bean id="securityFilter"
- class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
- <beans:property name="authenticationManager" ref="myAuthenticationManager" />
- <beans:property name="accessDecisionManager"
- ref="affirmativeBasedAccessDecisionManager" />
- <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource"/>
- </beans:bean>
采用默认的自定义的也是采用Spring默认的FilterSecurityInterceptor拦截器,accessDecisionManager也采用的是框架提供的affirmativeBasedAccessDecisionManager
采用投票者来判断是否授权。
- <beans:bean id="affirmativeBasedAccessDecisionManager"
- class="org.springframework.security.access.vote.AffirmativeBased">
- <beans:property name="decisionVoters" ref="roleDecisionVoter" />
- </beans:bean>
-
- <beans:bean name="roleDecisionVoter"
- class="org.springframework.security.access.vote.RoleVoter" />
-
- <beans:bean id="mySecurityMetadataSource"
- class="org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource">
- <beans:constructor-arg
- type="org.springframework.security.web.util.UrlMatcher" ref="antUrlPathMatcher" />
- <beans:constructor-arg type="java.util.LinkedHashMap"
- ref="securityRequestMapFactoryBean" />
- </beans:bean>
SecurityMetadataSource也是ss
web框架提供的DefaultFilterInvocationSecurityMetadataSource,只是初始化参数中,一个选择
antUrl匹配,还是正则匹配,另一个是提供自定义的通过securityRequestMapFactoryBean。在后者是一个
LinkedHashMap<RequestKey,
Collection<ConfigAttribute>>类型,就是每一个URL匹配模式,所需要角色的集合。
- @Service("securityRequestMapFactoryBean")
- public class SecurityRequestMapFactoryBean extends
- LinkedHashMap<RequestKey, Collection<ConfigAttribute>> {
-
- @Resource
- private ModuleDao moduleDao;
-
- @PostConstruct
- public void loadSecurityInfos(){
- List<Module> modules = moduleDao.getAll(new Module());
- for (Module module : modules) {
- RequestKey requestKey = new RequestKey(module.getPageUrl());
- Collection<ConfigAttribute> configAttributes = new LinkedList<ConfigAttribute>();
- for (final Role role : module.getRoles()) {
- configAttributes.add(new ConfigAttribute() {
- public String getAttribute() {
- return role.getCode();
- }
- });
- }
- this.put(requestKey, configAttributes);
- }
- }
-
- }
PS: 最终的件applicationContext-security.xml配置文件
[转]Spring Security 可动态授权RBAC权限模块实践
标签:
原文地址:http://www.cnblogs.com/ZhuRenWang/p/4773189.html