最近弄了一个keycloak鉴权相关demo(地址附文末), 可以让不熟悉的keycloak的同学有一个快速、直观的了解。
今天结合背后的技术概念,简单聊聊:鉴权(authentication)和授权(authorization)以及Oauth2、OpenID Connect、JWT 和 JWKS。
鉴权 VS 授权
这两个概念的英文太相近,真是傻傻分不清,不过中文还好。
鉴权(Authentication, 也作AuthN):判断你是谁,通过密码或者授权码之类凭证
授权(Authorization,也作AuthZ):授权用户或角色等访问资源的权限,
如下图:

举例来说会更清晰:
假如你需要让A帮忙喂宠物,你给A了一个一次性的密码Key让其可以通过你家门禁(鉴权)。
但A进去后,只有到厨房拿宠物粮和客厅喂宠物,不能到其他房间则是其持有密码Key的权限(授权)
Oauth2
Oauth2是一个授权的协议,为客户端授权提供了一系列授权的流程来获取授权的访问令牌(AccessToken),比如
- Authorization Code flow
 需要提供注册的clientID和clientSecret 
- Implicit flow
 省掉了- Code环节, 放松了对客户端的校验,牺牲安全性来提高效率,已不推荐 
- Authorization Code flow (with PKCE)
 需要提供注册的clientID和即时生成的- code challenge(像一次性的secret,不可被篡改) 
为什么需要Oauth2?
还拿喂宠物的例子来说,你找代理喂宠物,不会想把自己的密码直接给他,那太不安全,需要一个安全的机制来临时授予尽量少的权限给代理方。
OpenID connect (OIDC)
OIDC是在Oauth2协议基础上扩展的认证层,提供ID令牌(IDToken)可以让客户端通过认证来识别用户.
应该是当今最常用的鉴权实现协议,有很多相关实现的通用类库。
JWT && JWKS
上边提到的AccessToken和IDToken都是用Json Web Token(JWT)技术来实现的。
JWT分为三段(.分隔,各自base64Url编码)
- header
 包含如签名算法alg,签名公钥IDkid, 类型等
- payload
 包含令牌签发相关数据如签发人iss,过期时间exp,签发时间iat等,及自定义的数据如权限及用户标识等
 具体token所携带的信息可以通过jwt.io来查看
- signature
 token前两部分的签名,防止被篡改
这里校验可以用签名的公钥,可以在JSON Web Key Set(JWKS)中通过header的公钥idkid和payload的签发服务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反向代理
动图如下:
具体示例详见:https://github.com/NewbMiao/keycloak-authN, 有readme,一键启动。
如有疑问,请文末留言交流或邮件:newbvirgil@gmail.com本文链接 : https://newbmiao.github.io/2021/09/19/tech-behind-authentication.html
