微服务架构下应用散步在不同的服务器上,不是一个tomcat ,不能再基于Session
不同的服务不同的功能,都要有权限控制,不能再基于Session用Security
微服务权限控制用Redis:
微服务用Redis做权限控制数据不好存
要查Redis,
权限变动时数据库与redis需要同步,redis不好改,如果失败后果严重
微服务权限控制用JWT的优势:
不用查数据库,Token校验时能用RSA公钥顺利解析就可放行
实时,数据如权限发生变化后重新登录时不用与别的服务同步,旧jwt过期后生成新JWT把权限存到载荷中就行了
安全
主要做第三方授权,解决微服务不能再基于Session用Security的问题
网关校验Token是否是有效用户
资源服务中用Security做权限控制,资源服务会解析令牌,拿到用户的权限列表,然后赋值给Security,对于资源服务来说就是单体结构,
资源服务与资源服务之间也是双重校验 -> 检验token,校验权限
微信OpenId:微信号的加密字符串
1.用户登录,2.用户点击授权,3.拿到token令牌
类似原来的写法,能跳转登录界面和登录成功
见 my-hrm-itsource\hrm-security-parent\security-auth-server-2001
和 typora文档 1.1 创建一个用于认证的服务
变化点:
增加oauth2依赖包
security 主配置文件 WebSecurityConfig 配置认证管理器交给spring管理,授权模式为“password”时会用到,取代原来的两个自定义过滤器,不影响登录成功
AuthorizationServerConfig是用于oauth2整合security的配置类
根据之前案例回顾思路和流程:
上述流程总结:
1.用户登录,2.用户点击授权,3.拿到token令牌
对于oauth2就两步,1.用户点击“授权”操作后得到授权码,2.根据授权码换token令牌
oauth2整合的核心配置文件深度剖析:
即理解AuthorizationServerConfig如何实现上述流程
见typora文档
tips:如何不涉及第三方授权也可以不用oauth2,只用SpringSecurity+JWT+RSA做微服务授权
认证服务专门用来生产令牌,只有在登录时进入该服务,其他资源服务集成Security解析令牌并设置到Security框架中
但是如果认证服务升级比如用到oauth2其他功能,其他资源服务不知道
–> 都做认证和授权,加入网关来统一负责认证
权限控制由授权注解完成,授权注解生效需要Security框架或Security的认证管理器中有权限列表信息
主体思路
登录时进入认证服务,查数据库信息生成令牌
访问各资源前都要先进入网关,由网关解析令牌看是否合法,合法就放行并传送令牌到要转发的资源服务中
资源服务解析令牌,将权限列表设置到Security框架中,然后授权注解生效
资源服务都需要在网关中进行注册,注册之后前端能看到的地址只有网关一个
1.浏览器输入http://localhost:2020/servers/auth/oauth/authorize?client_id=webapp&response_type=code&redirect_uri=http://www.baidu.com会转发到http://192.168.43.82:2001/login.html进行登录
2.登录后再输入http://localhost:2020/servers/auth/oauth/authorize?client_id=webapp&response_type=code&redirect_uri=http://www.baidu.com还是要一直登录,(加了网关就会这样 服务端口不一样session不共享),
1.只能像以前先输入http://localhost:2001/oauth/authorize?client_id=webapp&response_type=code&redirect_uri=http://www.baidu.com,跳转登录完成登录,
2.再次输入http://localhost:2001/oauth/authorize?client_id=webapp&response_type=code&redirect_uri=http://www.baidu.com就会进入授权页面,点授权后会收到授权码
3.再通过http://localhost:2001/oauth/token?client_id=webapp&client_secret=secret&grant_type=authorization_code&code=iOEIFE&redirect_uri=http://www.baidu.com 获取令牌
由于上述第二步的问题造成授权码模式不好用所以换一种方式,如换为密码模式,直接postman输入http://localhost:2020/servers/auth/oauth/token?client_id=webapp&client_secret=secret&grant_type=password&redirect_uri=http://www.baidu.com&username=zs &password=123 获取令牌(不用再重复登录)
1.不再直接访问认证资源服务拿令牌,改走网关转发认证资源服务拿令牌
2.访问资源服务先经过网关,校验令牌合法性(是否能正常解析)
3.资源服务接收和解析令牌,通过oauth2存到Security中,不用再重写usernamepassword和basic过滤器
见typora文档 2.1 zuul整合aouth2 与 工程中
oauth2依赖包已整合内嵌了Security和JWT依赖
1.通过oauth2的密码模式,来测试是否可以获取token令牌
2.通过网关访问资源服务
oauth2生成的令牌与手动生成的令牌不一样,会有一个令牌的类型,所以在请求头的Authorization的令牌值前要加上令牌类型如“bearer”
3.通过网关访问资源服务后再用feign调用其他资源服务
这种情况下两个资源服务中的权限都要具备才能访问成功,并要自定义拦截器解决feign请求丢失请求头的问题
代码详解分别见typora文档2.2和resource-server-security-feign-common工程