简单聊聊鉴权背后的那些技术

文章目录

  1. 1. 鉴权 VS 授权
  2. 2. Oauth2
  3. 3. OpenID connect (OIDC)
  4. 4. JWT && JWKS
  5. 5. Keycloak

最近弄了一个keycloak鉴权相关demo(地址附文末), 可以让不熟悉的keycloak的同学有一个快速、直观的了解。

今天结合背后的技术概念,简单聊聊:鉴权(authentication)和授权(authorization)以及Oauth2OpenID ConnectJWTJWKS

鉴权 VS 授权

这两个概念的英文太相近,真是傻傻分不清,不过中文还好。

鉴权(Authentication, 也作AuthN):判断你是谁,通过密码或者授权码之类凭证

授权(Authorization,也作AuthZ):授权用户或角色等访问资源的权限,

如下图:

Authentication VS Authorization

举例来说会更清晰:

假如你需要让A帮忙喂宠物,你给A了一个一次性的密码Key让其可以通过你家门禁(鉴权)。
但A进去后,只有到厨房拿宠物粮和客厅喂宠物,不能到其他房间则是其持有密码Key的权限(授权)

Oauth2

Oauth2是一个授权的协议,为客户端授权提供了一系列授权的流程来获取授权的访问令牌(AccessToken),比如

  • Authorization Code flow
    需要提供注册的clientID和clientSecret
    Authorization Code flow
  • Implicit flow
    省掉了Code环节, 放松了对客户端的校验,牺牲安全性来提高效率,已不推荐
    Implicit flow
  • Authorization Code flow (with PKCE)
    需要提供注册的clientID和即时生成的 code challenge(像一次性的secret,不可被篡改)
    PKCE flow

为什么需要Oauth2?

还拿喂宠物的例子来说,你找代理喂宠物,不会想把自己的密码直接给他,那太不安全,需要一个安全的机制来临时授予尽量少的权限给代理方。

OpenID connect (OIDC)

OIDC是在Oauth2协议基础上扩展的认证层,提供ID令牌(IDToken)可以让客户端通过认证来识别用户.

应该是当今最常用的鉴权实现协议,有很多相关实现的通用类库。

JWT && JWKS

上边提到的AccessTokenIDToken都是用Json Web Token(JWT)技术来实现的。

JWT分为三段(.分隔,各自base64Url编码)

  • header
    包含如签名算法alg,签名公钥ID kid, 类型等
  • payload
    包含令牌签发相关数据如签发人iss,过期时间exp,签发时间iat等,及自定义的数据如权限及用户标识等
    具体token所携带的信息可以通过jwt.io来查看
  • signature
    token前两部分的签名,防止被篡改

这里校验可以用签名的公钥,可以在JSON Web Key Set(JWKS)中通过header的公钥idkidpayload的签发服务iss的配置服务中(/.well-known/openid-configuration)找到。

如demo中:

  • 签发服务(iss)
    http://localhost/auth/realms/myrealm
  • 配置发现(discovery configuration)
    http://localhost/auth/realms/myrealm/.well-known/openid-configuration
  • JWK公钥配置(jwks_uri)
    http://localhost/auth/realms/myrealm/protocol/openid-connect/certs

Keycloak

说这么一圈,回到demo的主题,keycloak,一种开源的身份及访问管理(IAM)服务。官方称,“为现代应用系统和服务提供开源的鉴权和授权访问控制管理”。

实现了Oauth2,OpenID Connet,Saml协议的单点登陆SSO,支持多种第三方身份服务Identity Provider(IdP) (OpenID Connect, SAML2.0 IdPs,Github,Google等)来做鉴权,方便简单可以开箱即用。

在我提供的demo中,主要展示了鉴权相关:

  • 获取token:在客户端(web页面)使用推荐的PKCE方式获取`accessToken
  • 校验token:用token issuer配置中jwks的公钥来验证token签名是否合法

相当于离线验证,只能知道token是否合法,不能知道token是否被失效等,更安全的方式是通过token introspection接口验证token是否还有效)

其中web页面内用了react,获取token用了@react-keycloak/web, token校验用了OpenPolicyAgent(单纯为玩,不是推荐用法)
为了避免网页跨域cors问题加了nginx反向代理

动图如下:
demo

具体示例详见:https://github.com/NewbMiao/keycloak-authN, 有readme,一键启动。

如有疑问,请文末留言交流或邮件:newbvirgil@gmail.com 本文链接 : https://newbmiao.github.io/2021/09/19/tech-behind-authentication.html