认证鉴权也可以如此简单—使用API网关保护你的API安全

2021-12-26 22:18:41 浏览数 (5)

随着企业数字化进程的发展,企业正在大量使用 API 来连接服务和传输数据,API 在带来巨大便利的同时也带来了新的安全问题,被攻击的 API 可能导致重要数据泄漏并对企业业务造成毁灭性影响。因此,API 安全正受到业界和学术界的广泛关注。

一、认证鉴权,必须要做的事情

通常来说,API 有两种典型类型 :一种是传统的SOAP API,另一种则是更为流行的RESTful API。

SOAP API使用Web安全性的内置协议(WS),这种协议会定义一套保密和身份验证的规则集,SOAP API支持两大国际标准机构(OASIS和W3C)制定的标准,他们结合使用 XML 加密、XML 签名和 SAML 令牌来验证身份和授权,因此SOAP API 是有 Web 安全性做保障的,但也需要更多的管理成本。

RESTful API通过使用HTTP和JSON进行传输,无需存储,也不需要重新打包数据,它速度很快,因此比较流行。

类比起来,使用RESTful API就像寄明信片,很快就能送达目的地,但明信片上所有的信息都是明文的,大家都能看到,因此会有安全隐患。

认证鉴权,就是保护API的常用方法。在对API分级后,对那些安全性需求较高的API增加认证鉴权机制,就相当于增加了一层访问的屏障。

1.1 什么是认证鉴权?

简单来讲,认证鉴权的本质就是——判断用户是否具备能够操作某种资源的权限。

具体来讲,这里包括了一些关键问题:

  • 认证(Authentication):系统如何正确分辨出操作用户的真实身份?
  • 授权(Authorization):系统如何控制一个用户该看到哪些数据、能操作哪些功能?
  • 凭证(Credential):系统如何保证它与用户之间的承诺是双方当时真实意图的体现,是准确、完整且不可抵赖的?
  • 保密(Confidentiality):系统如何保证敏感数据无法被包括系统管理员在内的内外部人员所窃取、滥用?
  • 传输(Transport Security):系统如何保证通过网络传输的信息无法被第三方窃听、篡改和冒充?
  • 验证(Verification):系统如何确保提交到每项服务中的数据是合乎规则的,不会对系统稳定性、数据一致性、正确性产生风险?

1.2 认证鉴权的主要方式

常用的认证方式包括:Basic认证(基本认证)、Digest认证(摘要认证)、App Secret Key HMAC、JWT认证、OAuth2认证。

1. Basic认证

HTTP Basic 是一个非常传统的API认证技术,也是一个比较简单的技术。

主要思路

  1. 将username和password使用冒号(:)拼起来
  2. 使用base64编码
  3. 将编码后的字符串放在HTTP头Authorization中,发送给服务端。
代码语言:txt复制
WWW-Authenticate: Basic Realm='xxxx'
  1. 服务端验证请求头,认证通过,返回200, 认证不通过,返回401。

问题:base64不是加密协议,因此相当于用户名密码在网络上明文传输,有密码泄露的风险。

2. Digest认证

Digest Access,指“HTTP摘要认证“。在Basic认证的基础上,增加了:1. 请求方需要对用户名、密码和域进行md5传输,保证不明文。2. 增加了随机数(nonce)和 qop(quality of protection),保证md5不固定。

主要思路

  1. 调用方发起一个普通的HTTP请求。
  2. 服务端返回401错误,并且在HTTP头里的 WWW-Authenticate 返回如下信息:
代码语言:txt复制
WWW-Authenticate: Digest realm="testrealm@host.com",
                        qop="auth,auth-int",
                        nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                        opaque="5ccc069c403ebaf9f0171e9517f40e41"

其中,nonce为服务端生成的随机数。

  1. 客户端进行MD5计算。
代码语言:txt复制
HA1 = MD5(username:realm:password)	// 服务端算法为MD5
HA1 = MD5(MD5(username:realm:password):nonce:cnonce)	// 服务端算法为MD5-sess,其中nouce为服务端随机数,cnonce为客户端随机数

HA2 = MD5(method:digestURI)		//qop为'auth'
HA2 = MD5(method:digestURI:MD5(entityBody))		//qop为'auth-int'

response = MD5(HA1:nonce:HA2)			//qop为'auth'
response = MD5(HA1:nonce:nonceCount:cnonce:qop:HA2)   //qop为'auth-int'
  1. 将编码后的字符串放在HTTP头Authorization中,发送给服务端。
代码语言:txt复制
GET /dir/index.html HTTP/1.0
Host: localhost
Authorization: Digest username="Mufasa",
                     realm="testrealm@host.com",
                     nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                     uri="/dir/index.html",
                     qop=auth,
                     nc=00000001,
                     cnonce="0a4f113b",
                     response="6629fae49393a05397450978507c4ef1",
                     opaque="5ccc069c403ebaf9f0171e9517f40e41"
  1. 服务端验证请求头,认证通过,返回200, 认证不通过,返回401。

问题:容易受到中间人攻击。服务器可以存储HA1,如果HA1被泄露,攻击者可以直接访问API内容。

3. App Secret Key HMAC

这种方式的主要特征有 1)引入App Secret Key来标识API调用者身份,2)引入HMAC防止消息被篡改。

HMAC:为了防止消息在传递过程中被篡改,可以引入MAC( Message Authentication Code),这是一种给消息签名的技术。在实现中,首先对消息进行MAC,得到一个摘要字串。接收方得到消息后,进行同样的计算,然后比较这两个MAC字符串,如果一致,则表明没有被修改过。而HMAC( Hash-based Authenticsation Code),指的是,利用Hash技术完成这一过程,比如使用SHA-256算法。

image.pngimage.png

App Secret Key:抽象出一个应用的概念,用来标识调用者的身份,每一个应用可以生成一个或多个Secret Id/Key。API所有者只给有权限的API访问者颁发相应的Secret Id/Key。API访问者请求时带上应用标识,服务端就可以识别调用者的信息,并进行更细粒度的权限管理。

HMAC App Secret Key:API访问者发送请求时,可以对应用标识使用HMAC计算出摘要字串,在HTTP头的 Authorization字段中放入相关信息发送到服务端。服务端会查询相关应用的信息,并验证签名,验证通过,返回200,否则返回401。

4. JWT认证

JWT(JSON Web Token)也是一种标准的认证解决方案,它也是使用MAC进行签名。

主要思路:

  1. 用户使用用户名和口令到认证服务器上请求认证。
  2. 认证服务器验证用户名和口令后生成JWT Token(HMAC-SHA256对称加密),然后将 base64(header).base64(payload).signature 作为 JWT Token返回客户端。
  3. 客户端在请求应用服务器资源时,带上JWT Token。
  4. 应用服务器将JWT Token传给认证服务器检查 JWT Token,确认签名是正确的。
  5. 认证服务器检查JWT Payload 和 签名,验证通过后,告诉应用服务器。
  6. 应用服务认为请求合法,返回请求的资源。

上述方式为使用HMAC-SHA256对称加密的方式生成JWT Token的主要过程,可以看到,在第4步,应用服务器拿到Token后,还需要去认证服务器去验证,这一步增加了网络开销。因此,JWT 还支持RSA非对称加密算法。

区别在于:使用RSA非对称算法,在认证服务器这边放一个私钥,在应用服务器那边放一个公钥,认证服务器使用私钥加密,应用服务器使用公钥解密,这样一来,第4步验证Token的过程就不需要应用服务器向认证服务器请求了。但是,RSA是一个很慢的算法,所以,虽然你省了网络调用,但是却费了CPU,尤其是Header和Payload比较长的时候。

对于这个问题的解法,有一个思路:如果我们把header 和 payload简单地做SHA256,这会很快,然后,我们用RSA加密这个SHA256出来的字符串,这样一来,RSA算法就比较快了,而我们也做到了使用RSA签名的目的。最后,我们只需要使用一个机制在认证服务器和应用服务器之间定期地换一下公钥私钥对就好了。

5. OAuth2.0 认证

OAuth2.0是目前最为广泛使用的认证解决方案。与它上一个版本OAuth1.0不同,它完全依赖于TLS/SSL的链路加密技术(HTTPS),完全放弃了签名的方式,因此与OAuth1.0是不兼容的。

OAuth2.0有两种主要的方式:授权码模式(Authorization Code Model)和凭证模式(Client Credential Model)。

第一种:授权码模式

授权码模式,是最常使用的OAuth 2.0的授权许可类型,它适用于用户给第三方应用授权访问自己信息的场景。

image.pngimage.png

主要思路:

1. 当用户(Resource Owner)访问第三方应用(Client)的时候,第三方应用会将用户跳转到认证服务器(Authorization Server),主要请求的是 /authorize API,其中的请求方式如下所示:

代码语言:txt复制
https://login.authorization-server.com/authorize?
        client_id=6731de76-14a6-49ae-97bc-6eba6914391e	// Client颁发的client_id
        &response_type=code		// 标识使用授权码模式
        &redirect_uri=http://example-client.com/callback/		// 返回client的地址
        &scope=read		// 权限范围标识
        &state=xcoiv98CoolShell3kch		// 随机的字符串,主要用于防CSRF攻击。

2. 当Authorization Server收到上述请求后,通过 client_id来检查 redirect_uriscope是否合法,如果合法,则弹出一个页面,让用户授权(如果用户没有登录,则先让用户登录,登录完成后,出现授权访问页面)。

3. 当用户授权同意访问以后,Authorization Server 跳转回 Client ,并以其中加入一个 Authorization Code。 如下所示:

代码语言:txt复制
https://example-client.com/callback?	
        code=Yzk5ZDczMzRlNDEwYlrEqdFSBzjqfTG		// 授权通过的授权码
        &state=xcoiv98CoolShell3kch		// 第一步发送的随机字符串

4. Client 使用 Authorization Code 向 Authorization Server 请求获得 Access Token。

代码语言:txt复制
POST /oauth/token HTTP/1.1
Host: authorization-server.com
 
code=Yzk5ZDczMzRlNDEwYlrEqdFSBzjqfTG		// 授权码
&grant_type=code		// 标识使用授权码模式
&redirect_uri=https://example-client.com/callback/		// 返回client的地址
&client_id=6731de76-14a6-49ae-97bc-6eba6914391e	
&client_secret=JqQX2PNo9bpM0uEihUPzyrh		

5. Authorization Server验证client_id, client_secret和 code没问题后,颁发Token并返回。

代码语言:txt复制
{
  "access_token": "iJKV1QiLCJhbGciOiJSUzI1NiI",		// 访问令牌
  "refresh_token": "1KaPlrEqdFSBzjqfTGAMxZGU",		// 用于刷新访问令牌
  "token_type": "bearer",			
  "expires": 3600,
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciO.eyJhdWQiOiIyZDRkM..."		// JWT Token
}

6. Client 在Authorization Header中带上 Access Token ,向应用服务器请求用户的资源。

代码语言:txt复制
GET /v1/user/pictures
Host: https://example.resource.com

Authorization: Bearer iJKV1QiLCJhbGciOiJSUzI1NiI

第二种:凭证模式

Client Credential 是一个简化版的API认证,主要是用于认证服务器到服务器的调用,也就是没有用户参与的的认证流程。

image.pngimage.png

主要思路:

Client用自己的 client_idclient_secret向认证服务器(Authorization Server) 申请 Access Token,然后使用Access Token直接请求应用服务器获取相关资源。

6. OICD(OpenID Connect 1.0)

OIDC是OpenID Connect的简称。OIDC=(Identity, Authentication) OAuth 2.0。它在OAuth2上构建了一个身份层,是一个基于OAuth2协议的身份认证标准协议。

我们知道,OAuth2.0 提供了Access Token来解决授权第三方客户端访问受保护资源的问题,OIDC在这个基础上提供了增加了身份认证信息,通过ID Token来解决第三方客户端标识用户身份认证的问题。

OIDC的核心在于在OAuth2.0的授权流程中,一并提供用户的身份认证信息(ID Token)给第三方客户端,ID Token使用JWT格式来包装,得益于JWT的自包含性,紧凑性以及防篡改机制,使得ID Token可以安全的传递给第三方客户端程序并且容易被验证。OIDC并不是新技术,它主要是借鉴OpenId的身份标识,OAuth2的授权和JWT包装数据的方式,把这些技术融合在一起就是OIDC。

image.pngimage.png

OICD 的术语

  1. EU:End User
  2. RP:Relying Party ,用来代指OAuth2中的受信任的客户端(Client),身份认证和授权信息的消费方;
  3. OP:OpenID Provider,有能力提供EU认证的服务(比如OAuth2中的授权服务),用来为RP提供EU的身份认证信息;
  4. ID Token:JWT格式的数据,包含EU身份认证的信息。
  5. UserInfo Endpoint:用户信息接口(受OAuth2保护),当RP使用Access Token访问时,返回授权用户的信息,此接口必须使用HTTPS。

ID Token

ID Token是一个安全令牌,是一个授权服务器提供的包含用户信息(由一组Cliams构成以及其他辅助的Cliams)的JWT格式的数据结构。ID Token的主要构成部分如下(使用OAuth2流程的OIDC)。

iss = Issuer Identifier:必须。提供认证信息者的唯一标识。一般是一个https的url(不包含querystring和fragment部分)。sub = Subject Identifier:必须。iss提供的EU的标识,在iss范围内唯一。它会被RP用来标识唯一的用户。最长为255个ASCII个字符。

aud = Audience(s):必须。标识ID Token的受众。必须包含OAuth2的client_id。

exp = Expiration time:必须。过期时间,超过此时间的ID Token会作废不再被验证通过。

iat = Issued At Time:必须。JWT的构建的时间。

auth_time = AuthenticationTime:EU完成认证的时间。如果RP发送AuthN请求的时候携带max_age的参数,则此Claim是必须的。

nonce:RP发送请求的时候提供的随机字符串,用来减缓重放攻击,也可以来关联ID Token和RP本身的Session信息。

acr = Authentication Context Class Reference:可选。表示一个认证上下文引用值,可以用来标识认证上下文类。

amr = Authentication Methods References:可选。表示一组认证方法。

azp = Authorized party:可选。结合aud使用。只有在被认证的一方和受众(aud)不一致时才使用此值,一般情况下很少使用。

注意:

  • ID Token通常情况下还会包含其他的Claims,用来标识EU的身份。
  • ID Token必须使用JWS进行签名和JWE加密,从而提供认证的完整性、不可否认性以及可选的保密性。

OICD主要流程

  1. RP发送一个认证请求给OP;
  2. OP对EU进行身份认证,然后提供授权;
  3. OP把ID Token和Access Token(需要的话)返回给RP;
  4. RP使用Access Token发送一个请求UserInfo EndPoint;
  5. UserInfo EndPoint返回EU的Claims,即用户信息。

其中,第2步中,OP对EU的认证是通过OAuth2.0来做的,因此也可以使用基于Authorization Code的认证方式。

基于Authorization Code的认证方式

这种方式使用OAuth2的Authorization Code的方式来完成用户身份认证,所有的Token都是通过Token EndPoint来发放的。

1. RP发送请求给OP,请求授权码。一个例子如下:

代码语言:txt复制
GET /authorize?
    response_type=code		
    &scope=openid profile email
    &client_id=s6BhdRkqt3
    &state=af0ifjsldkj
    &redirect_uri=https://client.example.org/cb HTTP/1.1
  Host: server.example.com

2. OP接收到认证请求之后,需要对请求参数做严格的验证,验证通过后引导EU进行身份认证并且同意授权。完成后,会重定向到RP指定的回调地址,并且把code和state参数传递过去。比如:

代码语言:txt复制
 HTTP/1.1 302 Found
 Location: https://client.example.org/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj

3. RP使用上一步获得的code来请求Token EndPoint,这一步同OAuth2。然后Token EndPoint会返回响应的Token,其中除了OAuth2规定的部分数据外,还会附加一个id_token的字段。id_token字段就是上面提到的ID Token。例如:

代码语言:txt复制
HTTP/1.1 200 OK

Content-Type: application/json

Cache-Control: no-store

Pragma: no-cache

  {

   	       "access_token": "SlAV32hkKG",
           "token_type": "Bearer",
           "refresh_token": "8xLOxBtZp8",
           "expires_in": 3600,
           "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
                       yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
                       NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
                       fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
                       AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
                       Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
                       NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
                       QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
                       K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
                       XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"
  }

4. RP拿到这些信息之后,需要对id_token以及access_token的有效性进行验证。具体验证规则参考:https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation

二、保护API安全,API网关做了什么

腾讯云API网关作为接入层,保护API安全是它理所当然的责任。目前,API网关支持的认证鉴权方式包括:应用认证、OAuth2.0认证和EIAM认证。

2.1 应用认证

API网关应用认证采用App Secret Key HMAC方式。客户端在调用 API 时,需要使用签名密钥对请求内容进行签名计算,并将签名同步传输给服务器端进行签名验证。

image.pngimage.png

使用方式:

API 的拥有者可以在 API 网关控制台的应用管理页面生成 App,每个 App 会携带一对签名密钥(ApiAppKey 和 ApiAppSecret),API 拥有者将 API 授权给指定的 App(App 可以是 API 拥有者颁发或者 API 调用者所有)后,API 调用者就可以用 App 的签名密钥来调用相关的 API 了。

image.pngimage.png
image.pngimage.png

客户端调用 API 时,需要使用已授权签名密钥对请求内容的关键数据进行加密签名计算,并且将 ApiAppKey 和加密后生成的字符串放在请求的 Header 传输给 API 网关,API 网关会读取请求中的 ApiAppKey 的头信息,并且根据 ApiAppKey 的值查询到对应的 ApiAppSecret 的值,使用 ApiAppSecret 对收到的请求中的关键数据进行签名计算,并且使用自己的生成的签名和客户端传上来的签名进行比对,来验证签名的正确性。只有签名验证通过的请求才会发送给后端服务,否则 API 网关会认为该请求为非法请求,直接返回错误应答。

更详细的使用方式可参考:https://cloud.tencent.com/document/product/628/55088

能带来什么:

  • 验证客户端请求的合法性,确认请求中携带授权后的 App Key 生成的签名。
  • 防止请求数据在网络传输过程中被篡改。

适用场景:

  • 希望记录API调用者的身份
  • 希望对APi调用者快速进行权限管理

2.2 OAuth2.0

API网关OAuth2.0 使用OICD的方式,需要授权API和业务API组合使用。授权API是用来接受用户凭证输入,生成JWT Token的API;业务API是接受JWT token输入,验证token,转发到业务后端的API。

具体流程:

image.pngimage.png
  1. 客户端请求授权API,发起认证请求,请求中携带用户的用户名和密码
  2. API网关将请求转发给授权API中配置的授权服务器;
  3. 授权服务器读取请求中的验证信息(比如用户名、密码)进行验证,验证通过后使用私钥生成标准的 ID Token,返回给API网关;
  4. API网关将携带ID Token的应答返回给客户端;
  5. 客户端请求网关的业务API,请求中携带token;
  6. API网关使用用户设定的公钥对请求中的token进行验证,验证通过后,将请求透传给业务API配置的后端服务;
  7. 后端服务进行业务处理后应答;
  8. API网关将业务应答返回给客户端。

能带来什么:

  • 保护业务API的安全性。
  • 用户可以使用自己的用户体系对自己API进行授权。

授权范围:

  • API网关会认为有效的token有权访问与该授权API绑定的所有业务API。因此,如果需要更细力度的权限管理,还需要后端服务自己解开token进行权限认证。
  • API网关会验证token中的exp字段,一旦这个字段过期了,API网关会返回401 Unauthorized状态码,同时返回error message提示Token过期。

加密算法:

为了使用的简洁性,目前API网关支持的加密算法为RSA SHA256,加密的位数为2048。暂不支持HMAC-SHA256方式。

使用方式:

  1. 生成一对JWK(JSON Web 密钥),用于token生成与验证。私钥用于授权服务器签发JWT,公钥配置到授权API中用于API网关对请求验签。
  2. 使用JWK中的私钥实现并部署颁发token 的认证服务。向客户颁发token的形式由用户根据具体的业务场景决定,可以将颁发token的功能部署到生产环境,配置成普通API后由访问者通过用户名密码获得,也可以直接在本地环境生成token 后,直接拷贝给指定用户使用。在前一种方式中,需要将认证服务的访问地址配置为授权API认证服务器地址。
  3. 将JWK的公钥配置在授权API的公钥中。
  4. 请求授权A.PI,获取ID Token(建议方式,可保护授权服务器以及ID Token安全性),也可以直接访问授权服务器相关服务获取Token或直接将生成的Token发放给相关用户。
  5. 请求授权API,获取ID Token(建议方式,可保护授权服务器以及ID Token安全性),也可以直接访问授权服务器相关服务获取Token或直接将生成的Token发放给相关用户。
  6. 使用已获取的 token 请求业务 API,请求示例为:
代码语言:txt复制
GET /work
   Host: http://service-cmrrdq86-1251890925.gz.apigw.tencentcs.com
   Authorization: Bearer id_token="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTIyNzk3MTAsImZvbyI6ImJhciIsImlhdCI6MTU5MjI3OTQxMCwianRpIjoiZlBGYlFZRkR4REx3d0lXTFl0aHBBQSIsIm5iZiI6MTU5MjI3OTQxMCwid3VwIjo5MH0.0JQquNRVCQ8n9hPV-mJi6Mku_7G3T1jFp68Sk2AYBijpzzBMQ1KOcREyo9G6QOpvdctynGOAPkL3cwqeTzkFhWgGj633pu_MdLjlectEBMGyVQIv6pL8OBMCHMQzTUTpHWJ_NoUkLpRLKGqZFFcXW8q7v4KeCbf8xHUa9OCH5VF2JxYOnFWDVgucSqao06r0Jaq64LDwKIhLw77ujheKpcBjRrf1kqoIpqk2qhb8CzxM36g_DawMadzKmX49dT-k7auNnI2xUtu5CZdXZ3lSmLeicXfGjc66rrH_acqUqipZRKeeQ5F3Ma467jPQaTeOKiCMHwS2_yp-sXNU2GzxOA"'

7. API网关解开Id token,校验有效性。校验通过,转发请求到业务API的后端,否则,拒绝请求,返回403。

适用场景:

  • 验证客户端请求的合法性,确认请求中携带授权后的 App Key 生成的签名。
  • 防止请求数据在网络传输过程中被篡改。

三、EIAM API网关,化繁为简的新思路

腾讯数字身份管控平台(EIAM)支持对用户身份的集中管理、用户认证、应用集成、SSO、授权管理、审计管理等能力,支持 SAML、CAS、JWT、OIDC、OAuth2.0 等多种协议,支持多种基于角色的访问控制(RBAC)模型。

上述的应用认证和OAuth2.0方式都提供了对API的安全性保护,但也存在相应的问题。

  • 对于应用认证方式,如果用户数目变多,需要考虑应用的管理安全问题;
  • 对于 OAuth2.0 方式,需要开发者自建和维护认证服务器。

因此,采用 EIAM 为 API 网关提供认证和鉴权能力可以为 API 调用提供更为安全和简便的方式。

解决方案特点:

EIAM API 网关解决方案,是通过API网关现有的OAuth2.0认证方式与EIAM集成的,底层基于OICD(OAuth2.0)协议

不同于API网关的OAuth2.0方式,新的方式有如下特点:

  • 可一键创建授权 API 和业务 API,轻配置;
  • EIAM 维护用户目录,免自建认证服务器;
  • 在认证能力基础上支持鉴权功能,保护 API 安全;
  • EIAM 内置多种 RBAC 模型,免自建鉴权服务器和授权模型;
  • 内置缓存机制,更快的访问速度;

具体来说,

1) 传统的OAuth2.0方式在创建授权API时需要填写较多参数,同时需要建立授权API与业务API的绑定关系,EIAM方式只需要最多4个参数,即可一键创建授权API和业务API。

2)传统的OAuth2.0方式需要自己实现颁发和校验Token的服务,EIAM方式可将该部分逻辑托管到EIAM上。

3)传统的OAuth2.0方式只会校验ID token的有效性,更细粒度的权限校验需要用户自己解开token进行,EIAM方式提供了用户可选的鉴权功能,API网关会结合EIAM对请求来源进行权限校验,对于未授权的用户,返回403,“Access not authorized”,表明用户没有通过鉴权。对于完成授权的用户,直接返回 API 后端调用结果。

4)传统的OAuth2.0方式用户需要自己维护授权关系,EIAM方式下,可将用户RBAC模型托管到EIAM上。

5)传统的OAuth2.0方式每次都要请求授权API和业务API,EIAM方式下,会优先使用本地鉴权方式,减少网络传输带来的时延,同时,会对授权资源列表进行缓存,在一定时间范围内实现更快速的访问。

具体流程:

使用 EIAM 认证方式,只需要三步:

  1. 创建认证方式为“EIAM 认证”的 API。
  2. 在 EIAM 中创建用户池和用户,并进行授权。
  3. 使用用户凭证调用 API 网关 API。

具体配置方法可参考https://cloud.tencent.com/document/product/628/59669

适用场景:

  • 不想自建认证服务器或授权模型
  • 希望业务快速接入OAuth2.0协议保护API安全
  • 具有较细粒度鉴权需求

四、我们是怎么做到的?

4.1 技术架构

API网关EIAM认证提供多种选项:

1) 提供两种认证与鉴权方式:“只认证不鉴权”与“既认证又鉴权”:

  • 选择“只认证不鉴权”方式,请求授权 API 时,API 网关将校验传入的用户访问凭证,认证通过后,颁发 id_token。使用 id_token 请求业务 API 时,API 网关将检验 id_token 的合法性,校验通过后转发给业务后端。
  • 选择“既认证又鉴权”方式,请求授权 API 时,API 网关将校验传入的用户访问凭证,认证通过后,颁发 id_token。使用 id_token 请求业务 API 时,API 网关将检验 id_token 的合法性,同时校验访问用户是否具有访问该 API 的权限,API 网关将只放行具有访问权限的用户请求。用户与资源的授权关系可在EIAM进行配置。

2) 提供两种应用类型:“非 Web 客户端”与“Web 客户端”:

  • 非 Web 客户端:适用于非 Web 客户端发起的API调用,如服务器端、C/S架构系统客户端、App 客户端、小程序客户端,能支持以 POST 方式发起请求,需要自行请求授权 API 获取 Token,再使用 Token 请求业务 API;
  • Web 客户端:适用于 Web 客户端发起的 API 调用,如浏览器、客户端应用 Web Viewer 等 Web 客户端,能支持以 Web 重定向方式接收返回信息。

针对不同配置,实现方案如下:

image.pngimage.png
image.pngimage.png

4.2 技术方案

1) 云API网关应用

EIAM支持多种协议类型的“应用”,可用于身份认证、单点登录等场景。

在API网关EIAM认证方式中,EIAM定制了”云API网关“类型应用,采用OAuth2 JWT作为API认证、授权的协议实现。由OAuth2串联用户认证流程,JWT Token带出用户身份、权限信息。

2)资源级授权

EIAM提供应用级授权、资源级授权功能。其中,资源级授权是指,基于RBAC访问模型,将应用下的指定资源授权予指定的授权对象。

在API网关EIAM认证方式中,API网关的一个API,对应EIAM应用下的一个资源,支持用户、用户组和组织机构对该资源的权限管理。一个API网关API,可以绑定多个EIAM应用,作为应用下的一个授权资源。

3)认证方式

基于OAuth2.0协议,EIAM提供授权码模式和密码模式两种模式进行认证。当API网关EIAM应用类型为"非Web客户端"时,使用密码模式,当API网关EIAM应用类型为"Web客户端"时,使用授权码模式,

4)鉴权方式

EIAM提供在线鉴权接口,API网关可以提供<应用id、用户Id、服务Id、API Id>信息来判断用户是否有权限访问该服务下的API。

为了优化性能,EIAM在返回id_token时,会将该用户具备访问权限的资源列表写入JWT 的 scope字段进行返回。API网关将该资源列表进行缓存,在之后的访问中使用本地鉴权方式,实现更快的鉴权。

五、未来,更简单更安全

保护API安全,是API网关作为接入层重要的能力,除了认证鉴权,API网关还提供了更多方式来保护API安全。他们包括:

  1. 链路加密
  2. 请求映射与转换;
  3. 参数校验;
  4. IP 访问控制;
  5. 跨域访问控制 CORS;
  6. 流量监控与保护;
  7. DDoS 防护能力;
  8. 与 Web 应用防火墙 WAF 结合;

欢迎访问API网关官网文档 https://cloud.tencent.com/document/product/628 或咨询相关同学进行了解。

在未来,我们也会致力于提供更多方式和更简单的配置,来保护API网关上API的安全性。

参考文献

https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation

https://www.cnblogs.com/lishiqi-blog/p/11164961.html

https://coolshell.cn/articles/19395.html#HTTP_Basic

https://en.wikipedia.org/wiki/Digest_access_authentication#Example_with_explanation

1 人点赞