Spring Security 流程



首先创建4个类
流程大致如下:
1、容器启动 加载系统资源与权限列表(HashMap) MyInvocationSecurityMetadataSourceService中的loadResourceDefine
@Service
public class MyInvocationSecurityMetadataSourceService implements
FilterInvocationSecurityMetadataSource { @Autowired
private PermissionDao permissionDao; private HashMap<String, Collection<ConfigAttribute>> map =null; /**
* 加载所有资源与权限的关系
*/
public void loadResourceDefine(){
map = new HashMap<>();
Collection<ConfigAttribute> array;
ConfigAttribute cfg;
List<Permission> permissions = permissionDao.findAll();
for(Permission permission : permissions) {
array = new ArrayList<>();
//角色名称
cfg = new SecurityConfig(permission.getName());
array.add(cfg);
map.put(permission.getUrl(), array);
} } /**
*返回请求资源所需要的权限
*/
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
if(map ==null) loadResourceDefine();
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
AntPathRequestMatcher matcher;
String resUrl;
for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) {
resUrl = iter.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<?> clazz) {
return true;
}
}
2、用户发出请求
3、过滤器拦截 MyFilterSecurityInterceptor中的doFilter()
@Service
public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
/**
* 过滤请求 调用FilterInvocationSecurityMetadataSource 资源和 MyAccessDecisionManager进行验证
*/ @Autowired
private FilterInvocationSecurityMetadataSource securityMetadataSource; @Autowired
public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) {
super.setAccessDecisionManager(myAccessDecisionManager);
} @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
/**
* FilterInvocation 把doFilter传进来的request、response、chain对象保存起来
*/
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
public void invoke(FilterInvocation fi) throws IOException, ServletException {
//fi里面有一个被拦截的url
//里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的所有权限 HashMap中
//再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够
//object为FilterInvocation对象
//
//1、获取请求资源的权限
//执行Collection<ConfigAttribute> attributes=securityMetadataSource.getAttributes(fi);
//2、是否拥有权限
//执行 this.accessDecisionManager.decide(authenticated,fi,attributes);
InterceptorStatusToken token = super.beforeInvocation(fi);
/**
* InterceptorStatusToken token = super.beforeInvocation(fi);会调用MyAccessDecisionManager中decide方法
* 和MyInvocationSecurityMetadataSource中getAttributes方法
*/
try {
//执行下一个拦截器
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
} @Override
public void destroy() { } @Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class; } @Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
}
4、取得请求资源所需权限MyInvocationSecurityMetadataSourceService中getAttributes()
5、匹配用户的权限和请求所需要的权限MyAccessDecisionManager中decide()
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {
/**
* @param authentication 用户具有的角色权限,认证的入口
* @param object 当前正在请求的受保护的对象
* @param configAttributes 受保护对象的配置属性—所具有的权限
* @throws AccessDeniedException
* @throws InsufficientAuthenticationException
*/
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
//如果访问资源不需要任何权限则直接通过
if(null== configAttributes || configAttributes.size() <=0) {
return;
}
ConfigAttribute c;
String needRole;
//遍历configAttributes看用户是否有访问资源的权限
for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {
c = iter.next();
needRole = c.getAttribute();
for(GrantedAuthority ga : authentication.getAuthorities()) {
//ga 用户所被赋予的权限,needRole 访问相应资源应具有的权限
if(needRole.trim().equals(ga.getAuthority())) {
return;
}
}
}
// 如果访问被拒绝,实现将抛出一个AccessDeniedException异常。
throw new AccessDeniedException("no right");
} @Override
public boolean supports(ConfigAttribute attribute) {
return true;
} @Override
public boolean supports(Class<?> clazz) {
return true;
}
}
6、登录
@Service
public class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口 @Autowired
UserDao userDao;
@Autowired
PermissionDao permissionDao; /**
*点击登录跳转 保存用户权限
*
*/
public UserDetails loadUserByUsername(String username) {
SysUser user = userDao.findByUserName(username);
if (user != null) {
List<Permission> permissions = permissionDao.findByAdminUserId(user.getId());
List<GrantedAuthority> grantedAuthorities = new ArrayList <>();
for (Permission permission : permissions) {
if (permission != null && permission.getName()!=null) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
grantedAuthorities.add(grantedAuthority);
}
}
return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
} else {
throw new UsernameNotFoundException("admin: " + username + " do not exist!");
}
} }
7、验证并授权
Spring Security 流程的更多相关文章
- Spring Security 概念基础 验证流程
Spring Security 概念基础 验证流程 认证&授权 认证:确定是否为合法用户 授权:分配角色权限(分配角色,分配资源) 认证管理器(Authentication Manager) ...
- 最简单易懂的Spring Security 身份认证流程讲解
最简单易懂的Spring Security 身份认证流程讲解 导言 相信大伙对Spring Security这个框架又爱又恨,爱它的强大,恨它的繁琐,其实这是一个误区,Spring Security确 ...
- Spring Security Oauth2 单点登录案例实现和执行流程剖析
Spring Security Oauth2 OAuth是一个关于授权的开放网络标准,在全世界得到的广泛的应用,目前是2.0的版本.OAuth2在“客户端”与“服务提供商”之间,设置了一个授权层(au ...
- Spring Security 案例实现和执行流程剖析
Spring Security Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架.除了常规的认证(Authentication ...
- SpringBoot集成Spring Security(7)——认证流程
文章目录 一.认证流程 二.多个请求共享认证信息 三.获取用户认证信息 在前面的六章中,介绍了 Spring Security 的基础使用,在继续深入向下的学习前,有必要理解清楚 Spring Sec ...
- Spring Security 认证执行流程
本文基于 Spring Security 5.x 推荐阅读: 项目集成Spring Security SpringSecurity 整合 JWT 一.外层-正常登陆调用 项目启动后会自动寻找 User ...
- 认证与授权】Spring Security系列之认证流程解析
上面我们一起开始了Spring Security的初体验,并通过简单的配置甚至零配置就可以完成一个简单的认证流程.可能我们都有很大的疑惑,这中间到底发生了什么,为什么简单的配置就可以完成一个认证流程啊 ...
- 【认证与授权】Spring Security的授权流程
上一篇我们简单的分析了一下认证流程,通过程序的启动加载了各类的配置信息.接下来我们一起来看一下授权流程,争取完成和前面简单的web基于sessin的认证方式一致.由于在授权过程中,我们预先会给用于设置 ...
- Spring Security认证流程分析--练气后期
写在前面 在前一篇文章中,我们介绍了如何配置spring security的自定义认证页面,以及前后端分离场景下如何获取spring security的CSRF Token.在这一篇文章中我们将来分析 ...
随机推荐
- AWS 数据库(七)
数据库概念 关系型数据库 关系数据库提供了一个通用接口,使用户可以使用使用 编写的命令或查询从数据库读取和写入数据. 关系数据库由一个或多个表格组成,表格由与电子表格相似的列和行组成. 以行列形式存储 ...
- ubuntu 18.04 安装搜狗输入法
安装 fcitxsudo apt install fcitx 配置输入法打开fcitx配置界面,点击桌面左下角的菜单,弹出如下桌面: 点击: “Input Method”,进入设置界面 点击 “OK” ...
- 剑指offer33:求按从小到大的顺序的第N个丑数。
1 题目描述 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 2 ...
- nohup 命令
nohup command > myout.file 2>&1 & 指定nohup.out的文件名 jobs -l 查看后台命令
- Linux中request_irq()中断申请与处理说明
1. 中断的理解 中断你可以理解为就是一种电信号,是由硬件设备产生的然后发送给处理器,处理器接收到中断后,就会马上向操作系统反映此信号,之后就是系统的工作了. 这里有两个注意的地方,第一中断是随时都 ...
- Yii2 redis 使用方法
/** * 基于 yii2.0 redis使用方法 *///项目根目录命令行执行 composer require --prefer-dist yiisoft/yii2-redis; //在配置文件中 ...
- Python查看模块
1.查看Python所有内置模块 按以下链接打开,每个模块有介绍,可以选择不同的版本 https://docs.python.org/3.6/library/index.html 2.查看Python ...
- centos6克隆虚拟机后,网络无法访问和启动
使用vmware安装centos6虚拟机时, 克隆虚拟机后无法访问网络. 原因是:产生了重复的网卡信息** 克隆后在70-persistent-net.rules文件中会多一行网卡信息,把第一行网卡信 ...
- ubuntu安装之后需要做什么
安装完ubuntu或者linux后应该做什么?首先在你安装完之后,都知道,很多系统都是有自带的一些软件之类,很多其实是不必要的,我们可以完全删掉,需要的时候再重装,那么安装完之后应该做什么呢? 1.智 ...
- pc端vue 滚动到底部翻页
html: <div class="list" ref="scrollTopList"> <div class="listsmall ...