首先创建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 流程的更多相关文章

  1. Spring Security 概念基础 验证流程

    Spring Security 概念基础 验证流程 认证&授权 认证:确定是否为合法用户 授权:分配角色权限(分配角色,分配资源) 认证管理器(Authentication Manager) ...

  2. 最简单易懂的Spring Security 身份认证流程讲解

    最简单易懂的Spring Security 身份认证流程讲解 导言 相信大伙对Spring Security这个框架又爱又恨,爱它的强大,恨它的繁琐,其实这是一个误区,Spring Security确 ...

  3. Spring Security Oauth2 单点登录案例实现和执行流程剖析

    Spring Security Oauth2 OAuth是一个关于授权的开放网络标准,在全世界得到的广泛的应用,目前是2.0的版本.OAuth2在“客户端”与“服务提供商”之间,设置了一个授权层(au ...

  4. Spring Security 案例实现和执行流程剖析

    Spring Security Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架.除了常规的认证(Authentication ...

  5. SpringBoot集成Spring Security(7)——认证流程

    文章目录 一.认证流程 二.多个请求共享认证信息 三.获取用户认证信息 在前面的六章中,介绍了 Spring Security 的基础使用,在继续深入向下的学习前,有必要理解清楚 Spring Sec ...

  6. Spring Security 认证执行流程

    本文基于 Spring Security 5.x 推荐阅读: 项目集成Spring Security SpringSecurity 整合 JWT 一.外层-正常登陆调用 项目启动后会自动寻找 User ...

  7. 认证与授权】Spring Security系列之认证流程解析

    上面我们一起开始了Spring Security的初体验,并通过简单的配置甚至零配置就可以完成一个简单的认证流程.可能我们都有很大的疑惑,这中间到底发生了什么,为什么简单的配置就可以完成一个认证流程啊 ...

  8. 【认证与授权】Spring Security的授权流程

    上一篇我们简单的分析了一下认证流程,通过程序的启动加载了各类的配置信息.接下来我们一起来看一下授权流程,争取完成和前面简单的web基于sessin的认证方式一致.由于在授权过程中,我们预先会给用于设置 ...

  9. Spring Security认证流程分析--练气后期

    写在前面 在前一篇文章中,我们介绍了如何配置spring security的自定义认证页面,以及前后端分离场景下如何获取spring security的CSRF Token.在这一篇文章中我们将来分析 ...

随机推荐

  1. Selenium IDE命令

    Selenium IDE中提供了丰富的操作命令,在Selenium IDE的Command的下拉列表框中可以选择使用这些命令. 下面介绍一些常用命令的使用. 1.open open(url) 在浏览器 ...

  2. iOS 多线程的简单理解(1) 方式 :同步 异步

    最近遇到特别糟糕的面试,过程中提到多次对多线程的处理问题,并没有很好的给予答复和解决,所以在这里做个简单的备案: 期望能更加了解和熟练使用 多线程技术: 下面都是自己的总结,如果存在不对的,或者不足, ...

  3. mysql数据库建表授权操作

    1.create schema [数据库名称] default character set utf8 collate utf8_general_ci;--创建数据库 采用create schema和c ...

  4. mongodb 内嵌数组查询问题: 如何限定返回与条件匹配的数组

    原文地址:https://segmentfault.com/q/1010000002943721

  5. 理解Hybrid接口的应用

    Hybrid接口既可以连接普通终端的接入链路又可以连接交换机间的干道链路,特允许多个vlan的帧通过,并可以在出接口方向将某些vlan帧的标签剥掉. 通过配置Hybrid接口,能过实现对VLAN标签的 ...

  6. R镜像源的切换

    如果是默认的R安装一般会很慢 install.packages(pkgs, lib, repos = getOption("repos"), contriburl = contri ...

  7. Jenkins在Mac上的安装与维护

    卸载 开篇提前说下, 因为很久之前用安装包装过的, 我要先卸载: /Library/Application\ Support/Jenkins/Uninstall.command 注意:如果没有权限的话 ...

  8. Deepin 15.11 install nvidia dirver[mei you an zhuang shu ru fa]

    1.firstly, exec: sudo vim /etc/modprobe.d/blacklist-nouveau.conf[create], and input [blacklist nouve ...

  9. Python——多态、检查类型

    一.多态 Python变量并不需要声明类型,同一个变量可以在不同的时间引用不同的对象,当一个变量在调用同一个方法,可以呈现出多种行为,而具体呈现出哪种行为由该变量引用的对象来决定,这就是多态. 先看一 ...

  10. Python TypeError: __init__() got multiple values for argument 'master'(转)

    转自:https://stackoverflow.com/questions/33153404/python-typeerror-init-got-multiple-values-for-argume ...