视频链接:SpringSecurity框架教程
文章源码:https://github.com/geyiwei-suzhou/spring-security
认证授权过程
单点登录 sso
(1)如果是基于Session,那么Spring-Security会对cookie里的sessionid进行解析,找到服务器存储的session信息,然后判断当前用户是否符合请求的要求
(2)如果是token,则是解析出token,然后将当前请求加入到Spring-security管理的权限信息中去
将token返回给前端,前端将token存入到cookie中,访问后端是将token放入header中,后端Spring Security取到token获取权限列表,比对是否有操作权限
需求分析
微服务权限管理案例主要功能:
- 登录(认证)
- 添加角色
- 为角色分配菜单
- 添加用户
- 为用户分配角色
数据模型
- 权限管理数据模型
- 菜单:id,name
- 角色:id,name
- 用户:id,name
- 角色菜单关系表:id,cid,rid
- 用户角色关系表:id,uid,rid
建表语句下载, 提取码: bhfc
-
案例涉及技术说明
- Maven:创建父工程:管理项目依赖版本
创建子模块:使用具体依赖 - Spring Boot:本质就是Spring
- MyBatisPlus 操作数据库框架
- Spring Cloud:
(1)Gateway 网关
(2)注册中心 Nacos
其他技术:
- Redis
- Jwt
- Swagger
前端技术
- Maven:创建父工程:管理项目依赖版本
搭建项目工程
- 创建父工程 acl_parent:管理依赖版本
- 在父工程创建子模块
(1)common
* service_base:权限配置
* spring_security:权限配置
(2)infrastructure
* api_gateway:网关
(3)service
* service_acl:权限管理微服务模块
整合网关和前端
- 网关:
修改api_gateway/application.properties中mysql、redis参数 - 前端
修改 config/dev.env.js、login.js 参数BASE_API: '"http://localhost:8222"'
url: '/admin/acl/login' url: '/admin/acl/index/info' url: '/admin/acl/index/logout' url: '/admin/acl/index/menu'
启动测试
- 启动Redis
- 启动Nacos
- 启动后端 api_gateway、service_acl
- 启动前端:
npm run dev
- 访问:用户名 admin、密码 111111
认证流程详解
- UsernamePasswordAuthenticationFilter
(1)第一步 过滤的方法,判断提交方式是否是post提交 AbstractAuthenticationProcessingFilter.doFilter
(2)第二步 调用子类的方法进行身份认证 认证成功之后把认证信息封装到对象里面 Authentication
UsernamePasswordAuthenticationFilter.attemptAuthentication 方法
子类中 attemptAuthentication 方法:判断post请求,获取提交的用户名密码、构造成对象标记为未认证,把请求一些属性信息设置到对象里,调用方法进行身份认证(调用userDetailsService)
(3)第三步 session策略处理 sessionStrategy.onAuthentication
(4)第四步
1 认证失败抛出异常,执行认证失败的方法 unsuccessfulAuthentication
ExceptionTranslactionFilter
2 认证成功,调用认证成功的方法 successfulAuthentication
2. ProviderManager
权限访问流程详解
ExceptionTranslationFilter过滤器和FilterSecurityInterceptor过滤器
- ExceptionTranslationFilter
(1)前端请求,直接放行
(2)如果抛出异常,进行捕获,进行处理 - FilterSecurityInterceptor
(1)判断请求是否有权限
(2)进行springmvc处理
认证信息共享
(1)认证成功的方法,把认证信息对象方法对象中
successfulAuthentication
SecurityContextHolder.getContext().setAuthentication(authResult);
(2)SecurityContext对象
对Authentication进行封装
(3)SecurityContextHolder
使用ThreadLocal和线程绑定
(4)SecurityContextPersistenceFilter