spring security实现简单的url权限拦截
在一个系统中,权限的拦截是很常见的事情,通常情况下我们都是基于url进行拦截。那么在spring security中应该怎么配置呢。
大致步骤如下:
1、用户登录成功后我们需要拿到用户所拥有的权限,并保存到当前的认证对象中。
|- SecurityUserDetailServiceImpl#loadUserByUsername(String) 在根据用户名获取到用户后,一起查询出用户拥有的权限
2、当用户访问某一个url时,我们需要判断当前访问的url所需要的权限当前认证的用户是否拥有。
|- 系统加载时需要加载出 所有的资源(url)与之对应的权限
|- 用户访问url时,如果是有权限判断的url,取出url所需要的权限和用户当前的权限进行一个比对
> 成功 放行
> 无权 拒绝
那么我们怎么知道我们拥有哪些权限呢?我们可以基于一个简单的rbac的权限模型来进行实现。系统中存在 用户(sys_user),角色(sys_role),资源(sys_resources),用于和角色多对多关系(sys_user_role),角色和资源也是多对多关系(sys_role_resource)。
在资源这张表中记录着url和url所需要的权限。
基于上一篇 "认识 spring security" 我们来做一个简单的修改,实现url权限的拦截。
二、编写一个方法实现系统中的url权限判断
/** * 系统中的安全资源决策 * * @描述 * @作者 huan * @时间 2017年11月4日 - 下午12:32:11 */@Slf4j@Component("securityResourceDecisionHandler")public class SecurityResourceDecisionHandler { /** * 保存的是url以及url所需要的权限 */ private static final Map> URL_AUTHS = new ConcurrentHashMap<>(); static { URL_AUTHS.put("/xx", Arrays.asList(new SimpleGrantedAuthority("01"))); URL_AUTHS.put("/xx/x", Arrays.asList(new SimpleGrantedAuthority("01"))); URL_AUTHS.put("/yy", Arrays.asList(new SimpleGrantedAuthority("0102"))); URL_AUTHS.put("/zz/**", Arrays.asList(new SimpleGrantedAuthority("010201"))); } AntPathMatcher pathMatcher = new AntPathMatcher(); /** * 自定义决策 * * @param authentication * 认证对象 * @param request * 请求的request对象 * @return true:有权限访问 false:无权限访问 */ public boolean auth(Authentication authentication, HttpServletRequest request) { String uri = request.getRequestURI().replace(request.getContextPath(), ""); for (Entry> entry : URL_AUTHS.entrySet()) { if (pathMatcher.match(entry.getKey(), uri)) { Collection extends GrantedAuthority> authorities = authentication.getAuthorities(); for (GrantedAuthority grantedAuthority : authorities) { if (entry.getValue().contains(grantedAuthority)) { return true; } } log.warn("当前访问的uri:{},需要的权限是:{},当前用户无此权限.", uri, entry.getValue()); return false; } } // 访问的是没有配置权限的功能,必须要登录用户才可以进行访问 if (authentication.isAuthenticated() && !Objects.equals("anonymousUser", authentication.getPrincipal())) { return true; } // 没有登录,直接返回false return false; }}
注: 注意一下 /zz/** 这个url所需要的权限是010201,而这个权限当前登录用户是没有的
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~