一、前言
在上一篇中,我们IdentityServer4的说明,认识到是一个基于OpenID Connect协议标准的身份认证和授权程序,并简单的对基础知识的认识以及区别说明,从OAuth、OpenID、OpenID Connect以及JWT等进行对比区别说明。
而在这一篇中,我们主要对IdentityServer4中涉及使用的特定的相关术语进行说明。
二、术语
2.1 身份认证服务器(IdentityServer)
IdentityServer 是基于OpenID Connect协议标准的身份认证和授权程序,它实现了OpenID Connect 和 OAuth 2.0 协议。
同样的角色,不同的文档使用不同的术语。在有些文档中,它(IdentityServer)可能会被叫做安全令牌服务器(security token service)、身份提供者(identity provider)、授权服务器(authorization server)、 标识提供方((IP-STS,什么是IP-STS)等等。
但是它们都是一样的,都是向客户端发送安全令牌(security token),
IdentityServer有许多功能:
- 保护你的资源
- 使用本地帐户或通过外部身份提供程序对用户进行身份验证
- 提供会话管理和单点登录
- 管理和验证客户机
- 向客户发出标识和访问令牌
- 验证令牌
2.2 用户(User)
用户是使用已注册的客户端访问资源的人。指在id4中已经注册的用户
2.3 客户端(Client)
客户端就是从identityserver请求令牌的软件,既可以通过身份认证令牌来验证识别用户身份,又可以通过授权令牌来访问服务端的资源。但是客户端首先必须在申请令牌前已经在identityserver服务中注册过。
实际客户端不仅可以是Web应用程序,app或桌面应用程序,SPA,服务器进程等。
客户端:web、app、桌面应用、SPA、服务器进程
2.4 资源(Resources)
资源就是你想用identityserver保护的东西,可以是用户的身份数据或者api资源。
每一个资源都有一个唯一的名称,客户端使用这个唯一的名称来确定想访问哪一个资源
在访问之前,实际identityserver服务端已经配置好了哪个客户端可以访问哪个资源,所以你不必理解为客户端只要指定名称他们就可以随便访问任何一个资源
用户的身份信息实际由一组claim组成,例如姓名或者邮件都会包含在身份信息中。
用户身份信息将来通过identityserver校验后都会返回给被调用的客户端
API资源就是客户端想要调用的功能——通常通过 Web API 来对 API 资源建模,但这不是必须的,如下说明:
通常以json或xml的格式返回给客户端,例如webapi,wcf,webservice,可以使其他类型的格式,这个要看具体的使用场景了。
2.5 身份令牌(Id Token)
OIDC对OAuth2最主要的扩展就是提供了ID Token。来解决第三方客户端标识用户身份认证的问题。
OIDC的核心在于在OAuth2的授权流程中,一并提供用户的身份认证信息(ID Token)给到第三方客户端,ID Token使用JWT格式来包装,得益于JWT(JSON Web Token)的自包含性,紧凑性以及防篡改机制,使得ID Token可以安全的传递给第三方客户端程序并且容易被验证。此外还提供了UserInfo的接口,用户获取用户的更完整的信息。
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。
(毕竟上述claim中只有sub是和EU相关的,这在一般情况下是不够的,必须还需要EU的用户名,头像等其他的资料,OIDC提供了一组公共的cliams,请移步这里http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)。另外ID Token必须使用JWS进行签名和JWE加密,从而提供认证的完整性、不可否认性以及可选的保密性。
简而言之ID Token就是JWT格式的数据,包含一个人类用户的身份认证的信息,一个ID Token的例子如下:
2.6 访问令牌(Access Token)
访问令牌允许客户端访问某个 API 资源。客户端请求到访问令牌,然后使用这个令牌来访问 API资源。访问令牌包含了客户端和用户(如果有的话,这取决于业务是否需要,但通常不必要)的相关信息,API通过这些令牌信息来授予客户端的数据访问权限。
OAuth2提供了Access Token来解决授权第三方客户端访问受保护资源的问题;
2.7 刷新令牌(Refresh Token)
Access Token 是客户端访问资源服务器的令牌。拥有这个令牌代表着得到用户的授权。然而,这个授权应该是临时的,有一定有效期。这是因为,Access Token 在使用的过程中可能会泄露。给 Access Token 限定一个较短的有效期可以降低因 Access Token 泄露而带来的风险。
然而引入了有效期之后,客户端使用起来就不那么方便了。每当 Access Token 过期,客户端就必须重新向用户索要授权。这样用户可能每隔几天,甚至每天都需要进行授权操作。这是一件非常影响用户体验的事情。希望有一种方法,可以避免这种情况。
于是 Oauth2.0 引入了 Refresh Token 机制。Refresh Token 的作用是用来刷新 Access Token。鉴权服务器提供一个刷新接口,例如:
http://xxx.xxx.com/refresh?refreshtoken=&client_id=
传入 refresh token 和 client_id,鉴权服务器验证通过后,返回一个新的 access token。为了安全,Oauth2.0 引入了两个措施:
1,Oauth2.0 要求,refresh token 一定是保存在客户端的服务器上的,而绝不能存放在狭义的客户端(例如移动 app、PC端软件) 上。调用 refresh 接口的时候,一定是从服务器到服务器的访问;
2,Oauth2.0 引入了 client_secret 机制。即每一个 client_id 都对应一个 client_secret。这个 client_secret 会在客户端申请 client_id 时,随 client_id 一起分配给客户端。客户端必须把 client_secret 妥善保管在服务器上,决不能泄露。刷新 access token 时,需要验证这个 client_secret。
于是,实际上的刷新接口应该是类似这样的:
http://xxx.xxx.com/refresh?refreshtoken=&client_id=&client_secret=
以上就是 Refresh Token 机制。 Refresh Token 的有效期非常长,会在用户授权时,随 Access Token 一起重定向到回调 url,传递给客户端。
三、总结
- 本篇主要是对IdentityServer4的说明,以及其中涉及常见的术语的表述说明。
- 从身份认证服务器、用户、客户端、资源以及各个令牌等进行对比区别说明。
- 在后续中会对多种授权模式,数据库持久化以及UI界面优化和常见问题,搭建一个完整可用的认证授权项目。
- 如果有不对的或不理解的地方,希望大家可以多多指正,提出问题,一起讨论,不断学习,共同进步。
四、参考
Terminology——常见术语