赞
踩
spring security里面的四个重要的类,都需自己去实现:
1、UserDetailsService 读取登录用户信息、权限
2、AbstractSecurityInterceptor 这个类是用来继承的,还要实现servler的Filter,作用过滤url
3、FilterInvocationSecurityMetadataSource 读取url资源
4、AccessDecisionManager 控制访问权限
流程图
以上转载自:http://blog.csdn.net/u011511684/article/details/31394493
以下关于我自己搭建security框架(使用数据库url控制)所遇问题+解决方式:
- @Override
- public void decide(Authentication authentication, Object object,
- Collection<ConfigAttribute> configAttributes)
- throws AccessDeniedException, InsufficientAuthenticationException {
@Override public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { SmUser user = null; try { user = smUserRepository.findByUserIdAndStatus(userName, BaseConstants.USER_STATUS); } catch (DataAccessException e) { logger.error(e.getMessage()); throw new UsernameNotFoundException(userName + "not exsit"); } UserDetails userDetails = null; //获取权限 List<GrantedAuthority> authories = new ArrayList<>(); //查询用户角色对应所有comCode List<String> roleComponentList = smComponentService.getComCodeByUserId(user.getUserId()); for (String roleComponent : roleComponentList) { GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(roleComponent); /** * 之前不好理解的就是authories集合中传什么值,有什么作用 * 其实就是相当于传一个唯一性标志(url也可以,主键也可以),目的是在重写的MyAccessDecisionManager类中作为权限对比的标志 */ authories.add(grantedAuthority); } if (user != null) { // userDetails = new User(user.getUserId(), user.getPassword(), true, true, true, true, authories); userDetails = new User(user.getUserId(), user.getPassword(), authories); } return userDetails; }
object参数其实就是输入的html的网址,比如:http如下,
object获取的就是/cdss
这个参数哪里来的:为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果
package com.jhmk.earlywaring.auth; import com.jhmk.earlywaring.entity.RoleComponent; import com.jhmk.earlywaring.entity.SmComponent; import com.jhmk.earlywaring.repository.RoleComponentRepository; import com.jhmk.earlywaring.repository.SmComponentRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.*; @Service public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource { @Autowired RoleComponentRepository roleComponentRepository; @Autowired private SmComponentRepository smComponentRepository; private HashMap<String, Collection<ConfigAttribute>> map = null; public void loadResourceDefine() { map = new HashMap<>(); Collection<ConfigAttribute> array; ConfigAttribute cfg; List<SmComponent> components = smComponentRepository.findAll(); for (SmComponent c : components) { array = new ArrayList<>(); cfg = new SecurityConfig(c.getComCode()); array.add(cfg); //用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value,array:url对应role的list集合 map.put(c.getComEntry(), array); } } /** * 用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value, * * @param o * @return * @throws IllegalArgumentException */ @Override public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException { if (map == null) loadResourceDefine(); //object 中包含用户请求的request 信息 HttpServletRequest request = ((FilterInvocation) o).getHttpRequest(); AntPathRequestMatcher matcher; String resUrl; Iterator<String> iterator = map.keySet().iterator(); while (iterator.hasNext()) { resUrl = iterator.next(); matcher = new AntPathRequestMatcher(resUrl); if (matcher.matches(request)) { return map.get(resUrl); } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> aClass) { return true; } }
参数作用:为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。其实用白话说就是他会先执行上图loadResourceDefine这个方法,查询出所有权限放入map中,然后呢,比如刚刚请求的是/cdss这个请求,他会获取/cdss对应的唯一标识(一般是主键,自己决定) ,判断是不是在map中,如果存在,则进行权限验证,不存在,则放过。
package com.jhmk.earlywaring.auth; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.Collection; import java.util.Iterator; @Service public class MyAccessDecisionManager implements AccessDecisionManager { /** * // decide 方法是判定是否拥有权限的决策方法, * //configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。 * * @param authentication CustomUserService中循环添加到 GrantedAuthority 对象中的权限信息集合.(用户所具有的权限) * @param object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); * @param configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。 * @throws AccessDeniedException * @throws InsufficientAuthenticationException */ @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { // TODO Auto-generated method stub System.out.println("MyAccessDescisionManager.decide()------------------验证用户是否具有一定的权限--------"); if (configAttributes == null) return; HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); if (matchers("/images/**", request) || matchers("/js/**", request) || matchers("/css/**", request) || matchers("/fonts/**", request) || matchers("/font/**", request) || matchers("/", request) || matchers("/login", request)) { return; } else { for (Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) { String needResource = iter.next().getAttribute(); //authentication.getAuthorities() 用户所有的权限 for (GrantedAuthority ga : authentication.getAuthorities()) { if (needResource.equals(ga.getAuthority())) { return; } } } } throw new AccessDeniedException("--------MyAccessDescisionManager:decide-------对不起,您没有权限登录此界面!"); } @Override public boolean supports(ConfigAttribute configAttribute) { return true; } @Override public boolean supports(Class<?> aClass) { return true; } private boolean matchers(String url, HttpServletRequest request) { AntPathRequestMatcher matcher = new AntPathRequestMatcher(url); if (matcher.matches(request)) { return true; } return false; } }如果错误,欢迎指正
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。