腾讯云API网关的OAuth 2.0集成

2021-12-04 21:30:06 浏览数 (1)

前言:API网关其实是个很有意思的产品,刚上手,尝试了一些新东西,感觉很好玩。

有个朋友看到我在学习,自己周末撸了一个网关,说很好玩。。。这就是差距吧~

1. API网关简介

API网关是腾讯云上流量治理的产品,一般起到承载流量入口的能力。它提供 API 托管服务,能提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。

为了方便理解,贴个图上来。给客户介绍的时候,我一般用下面一幅图做为微服务整体方案的介绍。而网关冲在最前面。

因为今天的主题主要不是介绍API网关,而是要谈Oauth即成,所以有其他问题的同学可以留言,也可以直接联系我。

2. Oauth集成的需求

2.1 什么是AoP

根据AoP(aspect-oriented programming)的设计理念,我们需要不断的提炼可以重用的能力做模块化,并且形成切面。比如我们在Java 代码里常用到的,下面是只有权限里有Admin权限的人才能执行下面的删除。

代码语言:javascript复制
@Scope(role="Admin") 
public void deleteRecord(String recordId){
  deleteById(recordId);
}

其实背后可能是这么一个切面

代码语言:javascript复制
@Before("execution(* com.yourpackage..*.*(..))")
public void checkScope(JoinPoint proceedingJoinPoint) throws Throwable {
    String scope = getCurrentScope(proceedingJoinPoint);
    isAllow(proceedingJoinPoint, scope);
}

基于这个设计理念,把鉴权抽象出来就成为了一个必然的选择。在日常的客户交流过程中,绝大部分还是非常认可这个设计理念的。

2.2 为什么要在API网关做鉴权

首先,流量要尽可能的在最上层管理,和安全防护同理。我们不会把WAF的防御放到微服务体系里去针对每个服务做配置,也不会希望业务代码里不停的在做鉴权和处理鉴权结果带来的Exception。因此约定俗成的方案就是在流量的入口处做鉴权。是否有别的方案可以选?肯定是有的,不同需求会有不同的方案。但是大致在允许的情况下,把鉴权往上放是没错的。

于是就引出了客户的需求,在API网关做鉴权。

2.3 实现方式

当前云上的API网关支持API Key / Oauth 2.0 / EIAM等认证方式。其中EIAM本质上是Oauth 2.0 token。所以客户可以选择使用自建的Oauth服务或者集成云上的EIAM。当前遇到的客户中,大部分都是计划使用云上的产品直接集成。因此EIAM就成了首选。

3. 如何配置APIGW EIAM

3.1 界面配置EIAM鉴权

API网关和EIAM做了深度的整合,因此不需要选择标准的Oauth鉴权方式,而是直接选择EIAM就可以。API网关的文档上有详细的配置介绍。文档上介绍了如何创建一个API,选择新建或使用已有的EIAM应用作为鉴权的对象。每一步都有详细的描述,按照文档即可完成操作。大概的内容如下:

  1. 确认EIAM已经开通,并创建一个用户,配置username/password并且登录到用户门户,确保客户已经激活。
  2. 创建API,配置一个前端接入。选择EIAM鉴权类型,并使用新建EIAM的应用,后端选mock就可以。
  3. 访问EIAM服务,授权用户访问新建的应用。
  4. 使用Postman或者类似的工具测试,第一步是拿到token,第二步是通过鉴权。

需要注意的是“只认证不鉴权”和“既认证又鉴权”的两个选项的区别,还有“非Web客户”和“Web客户”的区别。文档里也有详细的介绍。

用户登录门户不好找,所以我特意截了个图。

3.2 界面配置Oauth类型使用EIAM

“怎么证明EIAM集成是Oauth鉴权?”。这里只能换一个方式配置一个几乎一模一样的东西,但是API网关使用Oauth作为验证方式,而不是EIAM,但是还是去和EIAM做交互。

然后复杂度就上来了,首先创建EIAM的应用需要选择OIDC,这个是基于OAuth2.0 并且提供id_token的应用类型。

然后在API网关里的配置都可以在EIAM的【应用管理】->【应用信息】里找到。而用户授权可以在【授权管理】-> 【应用授权】里做。

而API网关鉴权接口的配置也不复杂,可以参考下面的截图,分别为前端和后端配置,类型为OAuth 2.0的授权API。而业务API只需要和授权API绑定一下就好了。

3.3 Cmd配置EIAM鉴权和Oauth鉴权

了解我的人都知道,如果没有必要,我是不会登录控制台的。能用代码解决的绝对不用界面。其实这个符合普遍IT行业的使用习惯,只是我们的产品不是总能做到而已。Terraform还没有集成,我调试通了tccli的命令行,在这里和大家做个分享。只是命令行无法存储状态,对自动化来说只能说提供了最最基础的支撑而已。

第一部分是EIAM的鉴权 - 暂时不支持

第二部分是Oauth的授权API创建

代码语言:shell复制
export APIGW_SERVICE_ID=service-xxxx
export APIGW_SERVICE_API_NAME=yagr-demo
export EIAM_APP_ID=6f209a8d-xxxx-xxxx-xxxx-ada444f0976c

# create auth-api
tccli apigateway CreateApi --cli-unfold-argument 
--ServiceId `echo $APIGW_SERVICE_ID` 
--ApiName $APIGW_SERVICE_API_NAME 
--ApiType NORMAL 
--AuthType OAUTH 
--ApiBusinessType OAUTH 
--Protocol HTTP 
--RequestConfig.Path /auth_token 
--RequestConfig.Method POST 
--ServiceType HTTP 
--RequestParameters.0.Name password 
--RequestParameters.0.Position QUERY 
--RequestParameters.0.Type string 
--RequestParameters.0.Required true 
--RequestParameters.1.Name username 
--RequestParameters.1.Position QUERY 
--RequestParameters.1.Type string 
--RequestParameters.1.Required true 
--ConstantParameters.0.Name client_id 
--ConstantParameters.0.Position QUERY 
--ConstantParameters.0.Desc client_id 
--ConstantParameters.0.DefaultValue `tccli eiam DescribeApplication --ApplicationId $EIAM_APP_ID | jq .ClientId -r` 
--ConstantParameters.1.Name client_secret 
--ConstantParameters.1.Position QUERY 
--ConstantParameters.1.Desc client_secret 
--ConstantParameters.1.DefaultValue `tccli eiam DescribeApplication --ApplicationId $EIAM_APP_ID | jq .ClientSecret -r` 
--ConstantParameters.2.Name grant_type 
--ConstantParameters.2.Position QUERY 
--ConstantParameters.2.Desc grant_type 
--ConstantParameters.2.DefaultValue password 
--ServiceParameters.0.Name username 
--ServiceParameters.0.Position QUERY 
--ServiceParameters.0.RelevantRequestParameterPosition QUERY 
--ServiceParameters.0.RelevantRequestParameterName username 
--ServiceParameters.1.Name password 
--ServiceParameters.1.Position QUERY 
--ServiceParameters.1.RelevantRequestParameterPosition QUERY 
--ServiceParameters.1.RelevantRequestParameterName password 
--ServiceConfig.Url `tccli eiam DescribeApplication --ApplicationId $EIAM_APP_ID | jq .AuthorizeUrl -r | sed -e "s/https:////g" | cut -d '/' -f 1 | sed 's/^/https:///g'` 
--ServiceConfig.Path "/auth/oauth2/token" 
--ServiceConfig.Method POST 
--OauthConfig.PublicKey  `tccli eiam DescribeApplication --ApplicationId $EIAM_APP_ID | jq .PublicKey -r` 
--OauthConfig.TokenLocation "method.req.header.authorization" 
--OauthConfig.LoginRedirectUrl `tccli eiam DescribeApplication --ApplicationId $EIAM_APP_ID | jq .AuthorizeUrl -r` 
--ServiceTimeout 60

# release service - this must be done to see the change available
tccli apigateway ReleaseService --ServiceId $APIGW_SERVICE_ID --EnvironmentName release --ReleaseDesc test

我大约花了5-6个小时才搞定(当然包括了很多的学习成本)而且还要感谢团队的几位专家提供专门的指导。怎么说呢,希望对大家有帮助

0 人点赞