SpringSecurity
- 权限设计 库表
Spring Security 必须跟Spring集成且只能在Web环境下运行。
Shiro相对独立,有自己的Ini配置(类似于Spring中的xml配置),且不仅可以在Web环境下运行还可以在非Web环境下运行。
RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。
- 权限分类
- UI权限 view粗粒度权限
- 自定义jsp标签:
C. 功能权限 方法调用 相对细粒度
-
- 设计模式(代理模式、责任链模式)
- 设计思想 AOP 编程思想
- 技术手段(Filter、Interceptor、环绕通知)
D. 数据权限 字段
-
- 数据库视图View
权限设计草图:
- 搭建SpringSecurity框架
- 搭建spring基本框架;
applicationContext.xml
mcv.xml
Web,xml中:
关键的东西到了注意!!!!!!!!
Security.xml中要注意:
- 学会如何用SpringSecurity文档去书写xml文件;
- 注意返回的bool值要设置为true;
- 注意自定义custom-filter时,要把auto-config=’true’去掉
- ROLE_是权限的标识不能乱改;
- SpringSecurity默认提供了很多的Filter
- 责任链模式的体现在过滤器栈中。先入后出,
7.死去活来学法,先学会应用,然后在追寻源码进行学习
8.自定义CustmUser继承User来用加个盐salt
下面是我总结的图:
并发session的控制:
当用户名密码不一致的时候需要自定义异常否则抛出401的错误
记住我功能:实现退出浏览器后再次进入浏览器也可以免密登录
Spring的发布与订阅
主要是spring提供的异步调用方法。例如京东生成订单是后,进行的仓库查询,等一系列的操作异步进行,提高用户的体验度
具体异步实现的代码如下:这只是一个测试异步体现的代码
注意;remember me 要自己实现接口去清除cookie否则退出操作,并没有完全退出,cookie中读取数据
为什么要用springsecurity呢
1.将用户登录,权限控制分离出来,达到和其他控制、逻辑代码完全分离。
2.在控制、逻辑代码里面,可以通过spring容器的到我们登录用户的信息,可插拔性的体现。
3.自定义的权限控制访问,不但是对某个URL可操控,同时可以对某个方法进行控制。
4.提供一些登录相关的操作,如记住我、登录成功跳转页面设定等等。
5.安全控制性好,对并发session可控性好。
自定义SpringSecurity
DelegatingFilterPorxy
FilterChainProxy
DelegatingFilterPorxy 入口
doFilter(request, response, filterChain)
invokeDelegate(delegateToUse, request, response, filterChain);
delegate.doFilter(request, response, filterChain){
1. FilterInvocation fi = new FilterInvocation(request, response, chain);
2. List<Filter>filters= getFilters(fi.getRequest());//获取功能Filter Stack
3. VirtualFilterChain virtualFilterChain = new VirtualFilterChain(fi, filters);
4. virtualFilterChain.doFilter(fi.getRequest(), fi.getResponse());//链式调度入口
}
重点学习:
private static class VirtualFilterChain implements FilterChain { private final FilterInvocation fi; private final List<Filter> additionalFilters; private final int size; private int currentPosition = 0; private VirtualFilterChain(FilterInvocation filterInvocation, List<Filter> additionalFilters) { this.fi = filterInvocation; this.additionalFilters = additionalFilters; this.size = additionalFilters.size(); } public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { if (currentPosition == size) { if (logger.isDebugEnabled()) { logger.debug(fi.getRequestUrl() + " reached end of additional filter chain; proceeding with original chain"); } fi.getChain().doFilter(request, response); } else { currentPosition++; Filter nextFilter = additionalFilters.get(currentPosition - 1); if (logger.isDebugEnabled()) { logger.debug(fi.getRequestUrl() + " at position " + currentPosition + " of " + size + " in additional filter chain; firing Filter: '" + nextFilter + "'"); } nextFilter.doFilter(request, response, this); } } } |
Ant风格