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.在这一篇文章中我们将来分析 ...
随机推荐
- CF1197D Yet Another Subarray Problem
思路: 使用动态规划,在经典的最大子段和解法基础上进行扩展.dp[i][j]表示以第i个数为结尾,并且长度模m等于j的所有子段的最大cost. 实现: #include <bits/stdc++ ...
- ubuntu 安装 typora
# or run: # sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA300B7755AFCFAE wget -qO ...
- 使用IDEA打开工程未显示左侧工程目录栏
1. 重启IDEA2. 删除要打开的项目文件夹下的.idea文件夹3. open打开项目即可 注意: 是重启IDEA,不是只关闭IDEA的单个窗口 参考: https://blog.csdn.net/ ...
- 设置linux系统时间的方法
尝试了好多,都是因为权限问题失败,但是总结出了几种思路: 1 通过linux指令进行设置: date -s "20091112 18:30:50" &&hwcloc ...
- go方法
go中的方法(method),跟函数(function)不是一个概念,一定要区分,它的概念与python中的类方法类似. go中是没有类的概念的,所以,go要想实现类 多种属性集合的功能的话,必须要使 ...
- pytorch1.0进行Optimizer 优化器对比
pytorch1.0进行Optimizer 优化器对比 import torch import torch.utils.data as Data # Torch 中提供了一种帮助整理数据结构的工具, ...
- ELK基础配置
前言 近期在研究日志系统的设计,感觉现在公司的子系统和接口太多了,日志看不过来,就想着有没有一种方法可以把各个程序的日志组合到一起.于是乎就搜到了ELK.开始对ELK的概念完全搞不懂,就照着各个平台文 ...
- 数据库中间件之mycat读写分离
mycat核心概念 逻辑库 mycat中定义.管理的数据库 逻辑表 逻辑库中包含的需分库分表存储的表 datanode 数据节点(分片节点),逻辑表分片的存放节点 datahost 数据主机(节点主机 ...
- Authentication failed for "http://xxxxxx"
1.配置用户信息 git config --global user.name [username] git config --global user.email [email] 2.查询用户信息 ...
- 无重复字符串的最长子串 python
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc&qu ...