NJU服务接入统一认证

NJU 目前正在使用的统一身份认证系统

对大部分校内用户而言,即使申请到 *.nju.edu.cn 的域名,其域名的所有权也不会直接移交到应用开发者,而是通过反代(通常是nginx)转发到开发者的应用服务器。

基于此实现了校内的统一身份认证。所有用户发往应用程序的流量均经过认证服务器转发,对于已登录的用户,认证服务器会在转发过程中带上用户信息。因此,应用程序的域名并不会解析到实际的应用服务,而是直接解析到认证服务器。认证服务器内部再通过 nginx 将流量代理回应用服务器。换言之,认证服务器拦截了所有的对应用的流量,只将带有认证信息的请求转发到应用;拦截没有认证信息的,并要求用户进行认证。

image-20250109223956231

优点

这样做无疑是让应用服务变得更加简单了。应用服务无需关注登录的细节,包括密码校验,错误密码重置等。应用默认所有的访问用户都进行了登录,只需要对用户登录ID进行权限校验即可。

对于校园内的简单应用,用户数量不大,这样做也缩短了开发周期和难度。

劣势

任何稍微复杂的应用都有自己的会话数据与状态需要保存,所以此点带来的简化相当有限。

流量全部流经统一认证服务器:应用服务器的一切流量全部流经统一认证服务器。

  • 统一认证服务器出现问题,会导致下游的所有服务向外暴露,导致虚假的用户访问;
  • 用户信息将被截获,导致用户信息暴露。

另外

  • 对于大规模场景,所有流量都需要通过统一认证服务,对统一认证服务器带来过多压力。

  • HTTPS 加密数据过早解密。由于用户流量在认证服务器上就被解密,认证服务器到应用服务器的通信是明文的。攻击者仅需要截取校园网上认证服务器与应用服务器之间的通信,即可泄露大量信息。

  • 认证服务器与应用服务器的鉴权是单向的,现有方案未提供 IP 以外的任何手段。一旦攻击者对应用服务器实施 IP 伪造攻击,或网络中传输中任意点进行篡改攻击,应用服务器就会认为此请求来自认证服务器而接受其中指定的用户信息。

  • 当认证服务器崩溃时,所有下级服务器直接对用户不可用,无论用户是否需要访问需要鉴权的资源。同时,一旦一个应用向上造成认证服务器出问题,所有应用都会受到连带的影响,这是不可接受的。

  • 在配置时,认证服务器和应用服务器的IP变化,都导致彼此的配置文件修改。

……

应用场景也非常有限。

其他统一身份认证鉴权方案

高校 选用**/**支持方式 支撑资料
上海交通大学 OAuth/OIDC 白雪松, 杜晋博 & 王罡. 高校信息化环境下OAuth授权体系的研究与实践. 华东师范大学学报(自然科学版) 240–245 (2015).https://developer.sjtu.edu.cn/auth/oidc.html
北京大学 OAuth 欧阳荣彬,杨旭. 基于OAuth的数据共享方案研究. 华东师范大学学报(自然科学版) 2015, 471 (2015). https://iaaa.pku.edu.cn/iaaa/oauth.jsp
中国人民大学 OAuth 直接询问
西安交通大学 CAS 冯兴利, 洪丹丹, 罗军锋 & 锁志海. 高校统一身份认证系统集群压力测试研究. 中国教育网络 76–78 (2018).
中国科学技术大学 CAS https://ustcnet.ustc.edu.cn/2015/0326/c11150a120769/page.htm
浙江大学 CAS https://zjuam.zju.edu.cn/cas/login
中国科学院 OAuth http://hf.cas.cn/xwzx1/tztg/202107/t20210728_6149276.html
中国科技云 OAuth https://www.cstcloud.cn/jswd
CARSI 教育网联邦认证和资源共享服务 SAML,对接:LDAP、OAuth 2、CAS https://carsi.atlassian.net/wiki/spaces/CAW/pages/27100896/5+11《CARSI 资源共享服务属性要求》
SEAC 上海教育认证中心 OAuth 冯骐, 朱宇红, 柯立新 & 沈富可. 上海是怎么做区域教育身份认证体系的? 中国教育网络 70–73 (2016)https://eac.cloud.sh.edu.cn/document/tech/OAuth.html

好的鉴权方式应当是应用服务的附加品,也就是说,用户的访问应当直接打到应用服务器上,再由应用服务器自主时候进行用户身份认证。

以下内容由GPT生成

CAS 鉴权

CAS鉴权的实现一般包括以下步骤:

  1. 用户访问应用程序(CAS客户端)
  • 用户访问某个需要认证的应用程序,假设这个应用程序已经与CAS服务器集成。
  • 如果用户尚未登录,应用程序会将用户重定向到CAS认证服务器进行身份验证。
  1. 重定向到CAS服务器
  • 用户的浏览器会被重定向到CAS服务器,通常带有目标URL(即用户最初访问的应用页面)作为参数。
  • 重定向请求一般是以https://cas-server/login?service={target-URL}的形式发送。
  1. 用户认证
  • 用户在CAS服务器上输入用户名和密码,CAS服务器验证用户身份。
  • 如果用户名和密码正确,CAS服务器生成一个票据(Ticket),通常是TGT(Ticket Granting Ticket),作为用户的身份标识。
  1. CAS服务器返回服务票据(Service Ticket, ST)
  • 用户身份验证成功后,CAS服务器生成一个ST(Service Ticket),并将其发送到用户的浏览器。
  • 用户的浏览器会将ST发送回最初的应用程序(CAS客户端)。
  1. 客户端向CAS服务器验证ST
  • 应用程序(CAS客户端)接收到ST后,会将该票据发送到CAS服务器进行验证。验证的请求通常是通过https://cas-server/serviceValidate?service={target-URL}&ticket={ST}的URL发送。
  • CAS服务器检查ST的有效性,确保它没有过期或被篡改。
  1. CAS服务器返回用户信息
  • 如果ST有效,CAS服务器会返回用户的身份信息(例如用户名、角色等)以及认证成功的标志。
  • 如果ST无效,CAS服务器会返回错误信息,应用程序则需要提示用户重新登录。
  1. 用户访问应用程序资源
  • 一旦CAS客户端验证通过,用户就可以访问应用程序的资源。应用程序通常会使用返回的用户身份信息来执行权限控制或角色验证等。
  1. 单点登录的持续性
  • 用户在整个CAS系统中只需要登录一次(即在CAS服务器上),然后可以无缝访问所有集成了CAS认证的应用程序,直到会话过期或用户主动登出。

用户授权(Authorization Request)

  • 用户尝试通过第三方应用(客户端)访问自己的受保护资源。
  • 客户端将用户重定向到授权服务器的授权端点,通常包括以下信息:
    • response_type=code:表示客户端希望使用授权码模式(Authorization Code Grant)。
    • client_id:客户端的唯一标识。
    • redirect_uri:授权服务器将用户重定向回的URI,包含授权码。
    • scope:客户端请求访问的权限范围(可选)。
    • state:客户端用来防止CSRF攻击的随机字符串(可选)。

例如:

1
https://authorization-server.com/authorize?response_type=code&client_id=client_id&redirect_uri=https://client.com/callback&scope=read write&state=random_state

用户登录与授权

  • 授权服务器提示用户登录(如果尚未登录),并请求用户授权该客户端访问其资源。
  • 用户同意授权后,授权服务器生成授权码,并将其附加到重定向URI中,返回给客户端。

例如:

1
https://client.com/callback?code=authorization_code&state=random_state

客户端请求访问令牌(Token Request)

  • 客户端接收到授权码后,将其与其他必要的参数(如client_idclient_secret)一起发送到授权服务器的令牌端点,交换访问令牌。

请求示例:

1
2
3
4
5
6
7
POST https://authorization-server.com/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
code=authorization_code
redirect_uri=https://client.com/callback
client_id=client_id
client_secret=client_secret

授权服务器返回访问令牌(Access Token)

  • 如果授权码有效,授权服务器会响应客户端一个包含访问令牌(Access Token)、令牌类型(通常是Bearer)以及可选的刷新令牌(Refresh Token)的JSON对象。

示例响应:

1
2
3
4
5
6
{
"access_token": "access_token_value",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "refresh_token_value"
}

客户端访问受保护资源

  • 客户端使用获得的访问令牌(Access Token)来请求资源服务器的受保护资源。
  • 客户端将访问令牌附加在HTTP请求的Authorization头中,发送给资源服务器:

请求示例:

1
2
GET https://resource-server.com/protected/resource
Authorization: Bearer access_token_value

资源服务器验证访问令牌

  • 资源服务器检查请求中包含的访问令牌是否有效。如果有效,资源服务器返回受保护资源;否则,返回错误(例如401 Unauthorized)。

(可选)使用刷新令牌获取新令牌

  • 如果访问令牌过期且客户端仍需访问受保护资源,客户端可以使用刷新令牌(Refresh Token)向授权服务器请求新的访问令牌。

请求示例:

1
2
3
4
5
6
POST https://authorization-server.com/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
refresh_token=refresh_token_value
client_id=client_id
client_secret=client_secret

授权服务器响应新令牌:

1
2
3
4
5
{
"access_token": "new_access_token_value",
"token_type": "Bearer",
"expires_in": 3600
}

references

统一认证交流.pptx