摘要
API可谓扮演了“技术胶水”的角色,能帮助企业内外进行不同业务逻辑和不同数据的连接和整合,API市场正逐步形成一个新的生态系统,对于调用者来说,能快速整合不同服务到自己的产品中,快速丰富产品功能;对提供者而言,能通过API将自己的服务,专业能力和专业数据变现。
解决方案
随着微服务架构体系的建立,API网关扮演着独木桥的角色,其出现在企业系统的边界,承担着企业内部与企业外部交互通信的作用,它除了需要保证数据交换之外,还需要对接入客户端身份认证,防止数据篡改等业务鉴权的功能之外,还承担了流控、协议转换等作用,其架构大概如下:
图乃盗用王延炯大神的.png
在业界比较流行的api网关有Kong、Gravitee、Zuul等,其主要是针对rest api等来做的,协议转换功能是没有的
基于zuul与oauth2来构建api网关
Oauth2
oauth2是一个搞授权的,对于Api网关来说,用oauth2来做业务鉴权是比较合适的选择,其大概有几种角色的定义:
- 资源拥有者(resource owner):能授权访问受保护资源的一个实体,可以是一个人,那我们称之为最终用户;
- 资源服务器(resource server):存储受保护资源,客户端通过access token请求资源,资源服务器响应受保护资源给客户端;
- 授权服务器(authorization server):成功验证资源拥有者并获取授权之后,授权服务器颁发授权令牌(Access Token)给客户端。
- 客户端(client):第三方应用,也可以是它自己的官方应用;其本身不存储资源,而是资源拥有者授权通过后,使用它的授权(授权令牌)访问受保护资源,然后客户端把相应的数据展示出来/提交到服务器。
而对于Api网关来说,网关扮演了资源服务器及授权服务器的角色
集成oauth2比较简单
- Pom依赖
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.12.RELEASE</version>
</dependency>
```
- 开启授权服务器
@Configuration
@EnableAuthorizationServer
public class OAuth2ServerConfiguration extends AuthorizationServerConfigurerAdapter {
}
- 开启资源服务器
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
}
基本上这三部就能把oauth2进行完美的集成,还有其他方面的工作,比如说token的存储,UserDetailsService、ClientDetailsService、ClientRegistrationService具体实现,及WebSecurity的定义等
详细可以查看<a href="https://github.com/linking12/saluki/tree/develop/saluki-gateway/src/main/java/com/quancheng/saluki/gateway/oauth2">oauth2</a>
zuul
zuul是netfix的api 网关,主要特色有:filter的PRPE(pre,route,post,error)模型、groovy的fitler机制,其中spring cloud对其有比较好的扩展,但是spring cloud对其的扩展感觉不是很完美,存在路由规则无法只能是通过配置文件来存储,而无法动态配置的目的,其中有一个人写了一个starter插件来解决路由规则配置到Cassandra的问题,详细请看:<a href="https://github.com/jmnarloch/zuul-route-cassandra-spring-cloud-starter">cassandra</a>,此插件针对的spring cloud zuul版本比较老,故我对他进行改进,将路由配置可以配置到mysql这样的关系型数据库中,详细请看:<a href="https://github.com/linking12/saluki/tree/develop/saluki-gateway/src/main/java/com/quancheng/saluki/gateway/zuul">zuul</a>
改动点有:
1:对DiscoveryClientRouteLocator的重新覆盖,该类的作用就是从yml中读取路由规则;
2:定义自己的Filter机制,这里主要是做了流控及协议转化的工作,这里主要是http->grpc的转换;
LimitAccessFilter:利用redis令牌桶算法进行流控
GrpcRemoteRouteFilter:http转化为grpc的协议转换
3:还有是添加路由到数据后,通知zuul重新刷新路由规则,通过spring的event来实现的;
以上就是用zuul和oauth2来构建网关的一些实际经验,仅抛砖引玉,其中api网关还有一些其他工作,比如服务编排,服务隔离等并没有体现,仅实现了限流、鉴权、协议转换三个基本功能点,而且与kong这样的Nginx网关相比,并发量支持比Kong要差好多,这点可以部署多节点来解决
详细代码 gateway
https://github.com/linking12/saluki/tree/develop/saluki-gateway
网友评论
java.lang.IllegalArgumentException: Principal must not be null
单独使用 Oauth2.0 和 Zuul 分发 都是好用的 只要在Oautn2.0 导入 zuul 包 就报错
需要什么特殊的配置么