Spring Security OAuth2.0认证授权四:分布式系统认证授权

Spring Security OAuth2.0认证授权系列文章

Spring Security OAuth2.0认证授权一:框架搭建和认证测试
Spring Security OAuth2.0认证授权二:搭建资源服务
Spring Security OAuth2.0认证授权三:使用JWT令牌

前面几篇文章讲解了如何从头开始搭建认证服务和资源服务,从颁发普通令牌到颁发jwt令牌,最终完成了jwt令牌的颁发和校验。本篇文章将会讲解分布式环境下如何进行认证和授权。

一、设计思路

分布式授权图.png

一般来说,一个典型的分布式系统架构如上图所示,这里进行一个简单的设计,来完成分布式系统下的认证和授权。

整体设计思路是使用OAuth2.0颁发令牌,使用JWT对令牌签名并颁发JWT令牌给客户端。既然决定使用JWT令牌了,则不需要再调用认证服务器对令牌进行验证了,因为JWT本身就包含了所需要的信息,而且只要验签成功,则可认为令牌可信任且有效。

如上所述,则可以如此设计:

用户请求登陆之后认证服务颁发令牌给用户,浏览器将令牌储存下来。

浏览器请求资源的的时候携带着令牌,网关拦截请求对令牌验证,验证的方法很简单,不请求认证服务而是直接使用密钥(对称或非对称)验签,只要验证成功则将jwt payload中的信息解析成明文放到请求头中转发请求到资源服务。

资源服务拿到明文信息,根据明文信息中的权限信息验证是否有权限访问该资源,有权限则返回资源信息,无权限则返回401。

综上,整体思路就是网关认证,资源服务鉴权。

典型的微服务架构下会有注册中心、网关等服务,接下来会依次介绍和搭建相关服务。

二、注册中心搭建

为了方便程序本地调试方便,这里使用eureka server作为服务注册中心,使用起来也非常简单

1.添加maven依赖 <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> 2.新建启动类 @SpringBootApplication @EnableEurekaServer public class RegisterServer { public static void main(String[] args) { SpringApplication.run(RegisterServer.class,args); } } 3.新建配置文件 spring: application: name: register-server server: port: 8765 #启动端口 eureka: server: enable-self-preservation: false #关闭服务器自我保护,客户端心跳检测15分钟内错误达到80%服务会保护,导致别人还认为是好用的服务 eviction-interval-timer-in-ms: 10000 #清理间隔(单位毫秒,默认是60*1000)5秒将客户端剔除的服务在服务注册列表中剔除# shouldUseReadOnlyResponseCache: true #eureka是CAP理论种基于AP策略,为了保证强一致性关闭此切换CP 默认不关闭 false关闭 client: register-with-eureka: false #false:不作为一个客户端注册到注册中心 fetch-registry: false #为true时,可以启动,但报异常:Cannot execute request on any known server instance-info-replication-interval-seconds: 10 serviceUrl: defaultZone: :${server.port}/eureka/ instance: hostname: ${spring.cloud.client.ip-address} prefer-ip-address: true instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}

然后启动启动类,访问浏览器,:8765,出现如下页面即表示已经成功

eureka server.png

二、网关搭建

这里选用spring cloud gateway作为网关(不是zuul)

1.添加maven依赖 <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--gateway 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>2.2.5.RELEASE</version> </dependency> <!--actuator 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- jwt依赖 --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency> </dependencies> 2.新建启动类 @SpringBootApplication public class GatewayServer { public static void main(String[] args) { SpringApplication.run(GatewayServer.class, args); } } 3.新建配置文件 server: port: 8761 spring: cloud: gateway: routes: - id: resource_server uri: "lb://resource-server" predicates: - Path=http://www.likecs.com/r** application: name: gateway-server eureka: client: service-url: defaultZone: :8765/eureka instance: prefer-ip-address: true instance-id: ${spring.application.name}:${spring.cloud.client.ip‐address}:${spring.application.instance_id:${server.port}}

如此,一个网关就已经搭建好了,但是还不具备我们想要的认证功能。

4.添加token全局过滤器

知识点有以下几点:

全局过滤器要实现GlobalFilter接口

为了实现token过滤器最先被调用,要实现Order接口并将优先级调到最大

使用JwtHelper工具类对jwt验签,签名的key必须和认证中心中配置的key保持一致

验签成功后将jwt中payload明文信息放到token-info的header值中传递给目标服务

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyyddg.html