SpringSecurity3.X权限原理(转)
这里给出一个简单的安全验证的实现例子,先说一下需求:
1.通过登录页面进行登录
2.用户登录前访问被保护的地址时自动跳转到登录页面
3.用户信息存储在数据表中
4.用户权限信息存在在数据表中
5.用户登录成功后访问没有权限访问的地址时跳转到登录页面
ok,以上就是一个基本的需求了,大部分的系统都是基于该需求实现登录模块的。
给出实现之前,先简单说明一下springsecurity的原理,
1.AccessDecisionManager
和我们一般实现登录验证采用filter的方式一样,springsecurity也是一个过滤器,当请求被springsecurity拦截后,会先对用户请求的资源进行安全认证,如果用户有权访问该资源,则放行,否则将阻断用户请求或提供用户登录,
在springsecurity中,负责对用户的请求资源进行安全认证的是AccessDecisionManager,它就是一组投票器的集合,默认的策略是使用一个AffirmativeBased,既只要有一个投票器通过验证就允许用户访问,
所以如果希望实现自己的权限验证策略,实现自己的投票器是一个很好的选择。
2.UserDetailsService
如果用户没有登录就访问某一个受保护的资源,则springsecurity会提示用户登录,用户登录后,由UserDetailsService来验证用户是否合法,既验证用户名和密码是否正确,同时验证用户是否具备相应的资源权限,
即对应的access的value。
如果用户验证通过,则由AccessDecisionManager来决定是否用户可以访问该资源。
下面给出具体实现:
web.xml
基本上都是这样配置,就不废话了。
Xml代码
- <</span> filter >
- <</span> filter-name > springSecurityFilterChain </</span> filter-name >
- <</span> filter-class > org.springframework.web.filter.DelegatingFilterProxy </</span> filter-class>
- </</span> filter >
- <</span> filter-mapping >
- <</span> filter-name > springSecurityFilterChain </</span> filter-name >
- <</span> url-pattern > *.do*" access = "HODLE" />
- <</span> logout logout-url = "/logout.do" invalidate-session = "true"
- logout-success-url = "/logout.jsp" />
- <</span> form-login login-page = "/index.do" default-target-url = "/frame.do"
- always-use-default-target = "true" authentication-failure-url = "/index.do?login_error=1" />
- <</span> session-management >
- <</span> concurrency-control max-sessions = "1" />
- </</span> session-management >
- </</span> http >
- <</span> beans:bean id = "loggerListener"
- class = "org.springframework.security.authentication.event.LoggerListener" />
- <</span> authentication-manager >
- <</span> authentication-provider user-service-ref = "userService" >
- <</span> password-encoder hash = "md5" />
- </</span> authentication-provider >
- </</span> authentication-manager >
- <</span> beans:bean id = "userService" class = "com.piaoyi.common.security.UserService" />
- <</span> beans:bean id = "accessDecisionManager"
- class = "org.springframework.security.access.vote.AffirmativeBased" >
- <</span> beans:property name = "decisionVoters" >
- <</span> beans:list >
- <</span> beans:bean class = "org.springframework.security.access.vote.RoleVoter" />
- <</span> beans:bean
- class = "org.springframework.security.access.vote.AuthenticatedVoter" />
- <</span> beans:bean class = "com.piaoyi.common.security.DynamicRoleVoter" />
- </</span> beans:list >
- </</span> beans:property >
- </</span> beans:bean >
- </</span> beans:beans >
UserService.java
Java代码
- public class UserService implements UserDetailsService{
- @Autowired
- private ISystemUserService userService;
- @Override
- public UserDetails loadUserByUsername(String username)
- throws UsernameNotFoundException {
- // TODO Auto-generated method stub
- SystemUser user = userService.findById(username);
- if (user == null )
- throw new UsernameNotFoundException( "The user name " + username
- + " can not be found!" );
- List resultAuths = new ArrayList();
- //增加access中配置的权限,实际上这里就是让所有登陆用户都具备该权限,
- //而真正的资源权限验证留给AccessDecisionManager来决定
- resultAuths.add(new GrantedAuthorityImpl( "HODLE" ));
- //验证用户名和密码是否正确,以及是否权限正确
- return new User(username, user.getPassword().toLowerCase(), user.isStatus(), true ,
- true , true , resultAuths);
- }
- }
DynamicRoleVoter.java
Java代码
- public class DynamicRoleVoter implements
- AccessDecisionVoter {
- @Autowired
- private ISystemUserService userService;
- private PathMatcher pathMatcher = new AntPathMatcher();
- @SuppressWarnings ( "unchecked" )
- public boolean supports(Class clazz) {
- return true ;
- }
- public boolean supports(ConfigAttribute attribute) {
- return true ;
- }
- public int vote(Authentication authentication, Object object,
- java.util.Collection arg2) {
- int result = ACCESS_ABSTAIN;
- if (!(object instanceof FilterInvocation))
- return result;
- FilterInvocation invo = (FilterInvocation) object;
- String url = invo.getRequestUrl();//当前请求的URL
- Set authorities = null ;
- String userId = authentication.getName();
- //获得当前用户的可访问资源,自定义的查询方法,之后和当前请求资源进行匹配,成功则放行,否则拦截
- authorities = loadUserAuthorities(userService.findById(userId));
- Map> urlAuths = authService.getUrlAuthorities();
- Set keySet = urlAuths.keySet();
- for (String key : keySet) {
- boolean matched = pathMatcher.match(key, url);
- if (!matched)
- continue ;
- Set mappedAuths = urlAuths.get(key);
- if (contain(authorities, mappedAuths)) {
- result = ACCESS_GRANTED;
- break ;
- }
- }
- return result;
- }
- protected boolean contain(Set authorities,
- Set mappedAuths) {
- if (CollectionUtils.isEmpty(mappedAuths)
- || CollectionUtils.isEmpty(authorities))
- return false ;
- for (GrantedAuthority item : authorities) {
- if (mappedAuths.contains(item.getAuthority()))
- return true ;
- }
- return false ;
- }
- }
SpringSecurity3.X权限原理(转)的更多相关文章
- Android 上SuperUser获取ROOT权限原理解析
Android 上SuperUser获取ROOT权限原理解析 一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android 玩家中常说的“越狱”有一个更深层次的认识. ...
- Android 获取ROOT权限原理解析
一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android玩家中常说的“越狱”有一个更深层次的认识. 二. Root的介绍 1. Root 的目的 可以让 ...
- MySQL权限原理及删除MySQL的匿名账户
MySQL权限系统的工作原理 MySQL权限系统通过下面两个阶段进行认证: (1)对连接的用户进行身份认证,合法的用户通过认证,不合法的用户拒绝连接: (2)对通过认证的合法用户赋予相应的权限,用户可 ...
- Sage Crm 权限原理分析
文字是11年写的,贴出来共享一下,先来一张表结构图: 一.区域.表名:[territories] 1.我们先来看看区域表的结构. 从图中前面都是不能为空的字段,都是很重要的.来介绍一下这些字段: Te ...
- 奇特的Local System权限(转载)
转载自:http://mp.weixin.qq.com/s?__biz=MzA3NTM1MzE4Nw==&mid=202597764&idx=1&sn=0cef1a40fb3c ...
- Android权限说明 system权限 root权限
原文链接:http://blog.csdn.net/rockwupj/article/details/8618655 Android权限说明 Android系统是运行在Linux内核上的,Androi ...
- android apk的签名和权限问题
一. android apk的签名问题(http://blog.csdn.net/lyq8479/article/details/6401093) 1.为什么要给Android应用程序签名? ...
- 学SpringMVC收藏
一个较完整的SpringMVC工程的配置 2014-01-22 17:17:25 标签:java spring springMVC 配置 springSecurity web.xml 原创作品,允许 ...
- DAY6 使用ping钥匙临时开启SSH:22端口,实现远程安全SSH登录管理就这么简单
设置防火墙策略时,关于SSH:22访问权限,我们常常会设置服务器只接受某个固定IP(如公司IP)访问,但是当我们出差或在家情况需要登录服务器怎么办呢? 常用两种解决方案:1.通过VPN操作登录主机: ...
随机推荐
- selenium webdriver入门
写在前面:最近在研究UI自动化测试的过程中,发现公司里通常用的是AutomanX框架,而这个框架实际上是基于selenium webdriver框架的,所以在编写测试用例时,很多语法都是直接使用sel ...
- Windows10使用Chocolatey安装mysql之后无法使用的解决办法
问题背景:使用了一台新的虚拟机,并且安装了Chocolatey作为Windows的包管理器,之后安装mysql 那么问题发生了,使用mysql命令根本没有任何反应,也不报错,但是安装的时候是提示安装成 ...
- 实战JAVA 高并发设计
一.同步(Synchronous)和异步(Asynchronous) 同步和异步通常用来形容一次方法调用,同步方法,调用者必须等到方法调用返回后,才能继续后续的行为,异步方法调用会立即返回,调用者就可 ...
- php session在高并发时可能存在的问题。
如果同一个客户端并发发送多个请求,而每个请求都使用了Session,那么PHP Session锁的存在会导致服务器串行响应这些请求,而不是并行.这是因为在默认情况下,PHP使用文件存储Session数 ...
- 前端基础之jQuery入门 01
jQuery介绍 jQuery是一个轻量级的.兼容多浏览器的JavaScript库. jQuery使用户能够更方便地处理HTML Document.Events.实现动画效果.方便地进行Ajax交互, ...
- 深入理解java虚拟机-第三章
1.概述 2.对象已死吗? 引用计数器 给对象添加一个引用计数器,每当有引用时,计数器加1,引用失效时,计数器减1:任何时刻计数器为0的对象就是不可能再被使用的. 若对象是循环引用,则无法处理.JVM ...
- poj 1952 最长公共子序列计数
看代码就懂了 不解释 3 1 1 1 1 2 2 2 1 1 1 3 第一个3 和最后一个 3 只需要一个就够了,,, #include<iostream> #include< ...
- tensorflow中常用激活函数和损失函数
激活函数 各激活函数曲线对比 常用激活函数: tf.sigmoid() tf.tanh() tf.nn.relu() tf.nn.softplus() tf.nn.softmax() tf.nn.dr ...
- 剑指offer-第四章解决面试题思路(字符串的排序)
题目:输入一个字符串,打印出该字符串的全排列. 思路:将整个字符串分成两部分,第一部分为一个字符,将该字符和该字符后面的字符(直到最后一个字符)依次交换,确定第一个字符:然后固定第一个字符,将后面的字 ...
- LA4992 Jungle Post
题意 PDF 分析 炸连续的比炸单独的好. 二分答案,每种炸连续的构成一些半平面,判断半平面交是否为空. 时间复杂度\(O(T n \log^2)\) 代码 这题卡常,排序的时候必须事先算出幅角,不然 ...