权限控制框架Spring Security 和Shiro 的总结
关于权限控制,一开始感觉比较难,后来先是接触了Spring Security 学起来也比较吃力,再是学习了Shiro,感觉简单很多。
总体来说这些框架,主要做了两个事情
Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
还做了一些事情,我也没有深入,主要就这么。
从以下配置文件可以看出。
<beans:bean id="myFilter" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="autheticationManager"></beans:property>
<beans:property name="accessDecisionManager" >
<beans:bean class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</beans:list>
</beans:property>
</beans:bean>
</beans:property>
<!-- resourceService在applicationContext*.xml中或注解定义 -->
<beans:property name="securityMetadataSource" ref="securityMetadataSource" />
</beans:bean>
这里有一个authenticationManager是做身份认证的,有一个accessDecisionManager是做授权管理的。还有一个是securityMetadataSource这里主要做的从数据库取出资源与角色的关系,为第二个授权做准备,授权又是根据用户的身份找出他的角色,根据角色判断是否有访问资源的权限。
先介绍这个 securityMetadataSource这里需要实现FilterInvocationSecurityMetadataSource接口,大致如下:
/**
* resourceMa
* resourceMap 存储的资源为<Url,Collection<ConfigAttribute>>,其中Collection<ConfigAttribute>为资源对应的角色集合,其构造方式为new SecurityConfig("ROLE_" + role.getRoleId().toString())
* resourceMap 里面存储的内容为<1个URL,对应得角色的集合>
* 加载所有的资源与角色的关系
*/
public void init() throws Exception {
resourceMap = new HashMap<String,Collection<ConfigAttribute>>();
List<Resource> resources = resourceDao.findAll();
for(Resource item:resources) {
String url = item.getUrlpath();
if(url != null) {
List<Role> roles = roleDao.getRolesByResourceId(item.getResourceid());
if(roles !=null && roles.size()>0) {
if(resourceMap.containsKey(item.getUrlpath())) {
Collection<ConfigAttribute> old = resourceMap.get(item.getUrlpath());
old.addAll(listToCollection(roles));
} else {
resourceMap.put(url, listToCollection(roles));
}
}
}
}
}
/**
* 将角色转化为ConfigAttribute
* @param roles
* @return
*/
private Collection<ConfigAttribute> listToCollection(Collection<Role> roles) {
Collection<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
for(Role role :roles) {
ConfigAttribute configAttribute = new SecurityConfig("ROLE_"+role.getRoleid().toString());
//list.add(new SecurityConfig("ROLE_" + role.getRoleid().toString()));
list.add(configAttribute);
}
return list;
} /**
* 将资源与权限的对应关系Map转化为Security需要的Collection
*/
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
for(Map.Entry<String, Collection<ConfigAttribute>> entry:resourceMap.entrySet()) {
allAttributes.addAll(entry.getValue());
}
return allAttributes;
} //返回所请求资源所需要的权限 public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { String requestUrl = ((FilterInvocation) object).getRequestUrl(); System.out.println("requestUrl is " + requestUrl); if(resourceMap == null) { try { init(); } catch (Exception e) { e.printStackTrace(); } } return resourceMap.get(requestUrl); }
上面前几个方法是在程序启动的时候执行,最后一个方法是在你要访问某个资源的时候自动调用的最终返回的是 Collection<ConfigAttribute> 权限集合。
accessDecisionManager授权管理,根据上面返回的权限集合,和用户登录存储的用户权限进行对比判断用户是否有访问权限,自己写授权管理的话需要实现AccessDecisionManager 接口,如下:
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
if(configAttributes == null) {
return;
}
//所请求的资源拥有的权限(一个资源对多个权限)
Iterator<ConfigAttribute> iterator = configAttributes.iterator();
while(iterator.hasNext()) {
ConfigAttribute configAttribute = iterator.next();
//访问所请求资源所需要的权限
String needPermission = configAttribute.getAttribute();
System.out.println("needPermission is " + needPermission);
//用户所拥有的权限authentication
for(GrantedAuthority ga : authentication.getAuthorities()) {
if(needPermission.equals(ga.getAuthority())) {
return;
}
}
}
//没有权限让我们去捕捉
throw new AccessDeniedException(" 没有权限访问!");
}
authenticationManager身份认证,主要包含登陆这些,框架一般会给我们提供form表单提交的处理接口,我们需要实现接口和配置一些相关配置。
<http auto-config="true" access-denied-page="/accessDenied.jsp" use-expressions="true">
<form-login login-page="/index.jsp" login-processing-url="/j_spring_security_check"
always-use-default-target="true" authentication-failure-url="/index.jsp?login_error=true"
default-target-url="/frame.jsp"
/>
<logout logout-success-url="/index.jsp"/>
<intercept-url pattern="/style/**" filters="none" />
<intercept-url pattern="/js/**" filters="none" />
<intercept-url pattern="/index.jsp" filters="none" />
<intercept-url pattern="/login.action" filters="none"/>
<intercept-url pattern="/frame.jsp" access="isAuthenticated()"/>
<anonymous />
<session-management invalid-session-url="/accessDenied.jsp">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
<!-- 将自己的过滤器加入到过滤器链中, 放在FILTER_SECURITY_INTERCEPTOR之前-->
<custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
</http>
<authentication-manager alias="autheticationManager">
<!-- 使用自定义UserDetailsService -->
<authentication-provider user-service-ref="userService"/>
</authentication-manager>
以上是Spring Security的配置,还需要在userService 登录验证里面实现UserDetailsService 接口。Shiro实现方式如下 :
Subject currentUser = SecurityUtils.getSubject();
System.out.println(EncryptUtils.encryptMD5(user.getPassword()));
UsernamePasswordToken token = new UsernamePasswordToken(
user.getUsercode(), EncryptUtils.encryptMD5(user.getPassword()));
token.setRememberMe(true);
try {
currentUser.login(token);
} catch (AuthenticationException e) {
modelView.addObject("message", "login errors");
modelView.setViewName("/login");
e.printStackTrace();
}
accessDecisionManager
权限控制框架Spring Security 和Shiro 的总结的更多相关文章
- 了解权限控制框架shiro 之实际应用.
Apache Shiro 1.权限控制分为 a.粗粒度 URL 级别权限控制 b.细粒度方法级别权限控制 2.使用shiro进行权限控制主要有四种主要方式 : a. 在程序中 通过 Subje ...
- 项目一:第十二天 1、常见权限控制方式 2、基于shiro提供url拦截方式验证权限 3、在realm中授权 5、总结验证权限方式(四种) 6、用户注销7、基于treegrid实现菜单展示
1 课程计划 1. 常见权限控制方式 2. 基于shiro提供url拦截方式验证权限 3. 在realm中授权 4. 基于shiro提供注解方式验证权限 5. 总结验证权限方式(四种) 6. 用户注销 ...
- Spring Security和Shiro的比较和使用
https://blog.csdn.net/it_java_shuai/article/details/78054951 Spring Security和Shiro的比较和使用 2017年09月21日 ...
- Spring Boot + Spring Cloud 实现权限管理系统 (Spring Security 版本 )
技术背景 到目前为止,我们使用的权限认证框架是 Shiro,虽然 Shiro 也足够好用并且简单,但对于 Spring 官方主推的安全框架 Spring Security,用户群也是甚大的,所以我们这 ...
- Flex-Security权限控制框架
转自:http://code.google.com/p/flex-security/ flex UI组件权限控制框架 一.快速开始 1) 下载并添加flex_security.swf在你的flex l ...
- WPF权限控制框架——【4】抛砖引玉
写第一篇"权限控制框架"系列博客是在2021-01-29,在这不到一个月的时间里,收集自己零碎的时间,竟然写出了一个"麻雀虽小,五脏俱全"的权限控制框架:对于一 ...
- 权限控制框架Shiro简单介绍及配置实例
Shiro是什么 http://shiro.apache.org/ Apache Shiro是一个非常易用的Java安全框架,它能提供验证.授权.加密和Session控制.Shiro非常轻量级,而且A ...
- shiro权限控制(一):shiro介绍以及整合SSM框架
shiro安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证.授权.加密和会话管理等功能 . shiro能做什么? 认证:验证用户的身份 授权:对用户执行访问控制:判断用户是 ...
- 第十九章 动态URL权限控制——《跟我学Shiro》
目录贴:跟我学Shiro目录贴 用过Spring Security的朋友应该比较熟悉对URL进行全局的权限控制,即访问URL时进行权限匹配:如果没有权限直接跳到相应的错误页面.Shiro也支持类似的机 ...
随机推荐
- XStream和Json
XStream的作用 XStream可以把JavaBean对象转换成XML! 通常服务器向客户端响应的数据都是来自数据库的一组对象,而我们不能直接把对象响应给响应端,所以我们需要把对象转换成XML再响 ...
- Spring学习之Jar包功能介绍(转)
spring.jar 是包含有完整发布模块的单个jar 包.但是不包括mock.jar, aspects.jar, spring-portlet.jar, and spring-hibernate2. ...
- R与数据分析旧笔记(十四) 动态聚类:K-means
动态聚类:K-means方法 动态聚类:K-means方法 算法 选择K个点作为初始质心 将每个点指派到最近的质心,形成K个簇(聚类) 重新计算每个簇的质心 重复2-3直至质心不发生变化 kmeans ...
- Android Log工具类
import java.text.SimpleDateFormat; import java.util.Date; import android.util.Log; public class LogU ...
- input 输入框获得/失去焦点时隐藏/显示文字(jquery版)
input输入框在获得或失去焦点时隐藏或显示文字,这样的焦点效果想必很多朋友在填写form表格的时候都曾见识过吧,本文使用jquery实现以下,感兴趣的朋友可以参考下哈 大家可以看效果图的搜索输入框, ...
- 树莓派高级GPIO库,wiringpi2 for python使用笔记(一)安装
网上的教程,一般Python用RPi.GPIO来控制树莓派的GPIO,而C/C++一般用wringpi库来操作GPIO,RPi.GPIO过于简单,很多高级功能不支持,比如i2c/SPI库等,也缺乏高精 ...
- python练习之list
请用索引取出下面list的指定元素: # -*- coding: utf-8 -*- L = [ ['Apple', 'Google', 'Microsoft'], ['Java', 'Python' ...
- CSS Flex
关于flex 请看这里 https://css-tricks.com/snippets/css/a-guide-to-flexbox/ 太详细啦!!! 还通俗易懂!!! 没啥好说的 不过上面那篇文 ...
- Initialization failed for block pool Block pool(转载)
2014-06-18 20:34:59,622 FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed ...
- NAND闪存颗粒结构及工作原理
NAND闪存是一种电压元件,靠其内存电压来存储数据,现在我们就来谈谈它的结构及工作原理. 闪存的内部存储结构是金属-氧化层-半导体-场效晶体管(MOSFET),里面有一个浮置栅极(Floating G ...