Spring Cloud OAuth2分布式权限校验,如何实现疑问?

摘要:分布式权限校验 现在有一个登录问题,假如需要用户登录之后才能查询图书和借阅图书。那要怎么设计? 单体应用的权限校验原理: 浏览器向服务端发送请求,访问网站 服务端接收请求后,创建一个sessionid,存储在服务端,然后发送给浏览器作为Co
分布式权限校验 现在有一个登录问题,假如需要用户登录之后才能查询图书和借阅图书。那要怎么设计? 单体应用的权限校验原理: 浏览器向服务端发送请求,访问网站 服务端接收请求后,创建一个sessionid,存储在服务端,然后发送给浏览器作为Cookie保存 以后浏览器每次请求都携带这个cookie。这样服务端根据cookie中的sessionid判断是哪个用户。 但是分布式系统,各个微服务独立部署,用户登录了用户服务后,借阅服务和图书服务会知道用户登录了吗? 用户登录后,session中的用户数据保存在用户服务中,其他服务没有对应信息,按怎么能让其他服务获取这些信息呢,实现服务间的session同步呢? 将session移出服务器,统一存放!比如存到redis或者MySQL,这样就能保证所有服务获得session。 具体的实现步骤如下: 为每个服务引入依赖: <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 修改每个服务配置文件: spring: session: # 存储类型修改为redis store-type: redis redis: # redis 服务器信息 host: localhost 这样设置之后,每个服务只有在登录成功后才能访问! 只要在一个服务登录成功,其他服务就会直接调用,不用重复登录! 注意,如果是服务A 调用服务B,用户在服务B登录,然后访问服务A。那么访问是失败的! 因为服务A没有验证,请求没有携带有效cookie,验证失败,导致其无法访问服务B。 OAuth 2.0 实现单点登录 上面虽然解决了session共享问题,但是由于每个服务都有自己的验证模块,导致整个系统存在冗余功能,那么能否实现只有一个服务进行登录,然后可以访问其他的服务呢? 单点登录正好解决这一问题! 一些常见的第三方登录就是使用这种方式:比如淘宝和咸鱼可以使用支付宝账号登录,虽然他们属于三个不同的应用系统,需要获取支付宝用户信息并授权给其他应用。就要使用OAuth 2.0实现第三方授权。那么到底是怎么实现的呢? OAuth 2.0一共有四种授权模式: 客户端模式:最简单的一种模式。 先向验证服务器请求获取一个token(令牌) 拿到令牌后去访问对应的资源(比如借阅信息,这样资源服务器才能知道访问者是谁以及是否登录成功) 这里的客户端可以是web、App、小程序或者第三方服务 这种模式比较简单,但是失去了用户验证的意义,压根就不是给用户校验准备的,更适合服务内部调用的场景! 密码模式:相比客户端模式,多了用户名和密码信息,用户需要提供用户名和密码才能获取到token 这种模式有一个缺点:会直接将账号密码信息泄露给客户端(或者第三方应用),这样风险很大,一般不会使用这种模式! 隐式授权模式:用户访问服务时,会重定向到认证服务器,认证服务器返回用户一个认证页面,等待用户授权,用户填写信息完成授权后,认证服务器返回token。用户再携带token去访问服务。 这种模式适合没有服务端的第三方应用页面,验证都是在验证服务器进行,不会泄露敏感信息,但是依然存在泄露token的风险! 授权码模式:最安全的一种模式,也是推荐使用的模式,手机上很多APP都是使用这种模式! 这种模式不会直接返回token,而是返回授权码,真正的token时通过应用服务器访问验证服务器获取的。
阅读全文