网站安全认证系统的设计变迁

openkk 12年前

     网站在从小到大的发展历程中,安全认证系统是如何变迁的?

     下面我们从其发展的几个阶段来分下:

     

     阶段1:

     起步,注册用户很少,两台服务器,一台应用服务器,一台数据库服务器。

     用户登陆后在应用服务器记录用户 session (通常就是 tomcat session)。

     当用户请求受保护资源(网页)时,首先请求经过一个安全认证过滤器进行拦截,并调用认证模块进行检测用户是否登陆。

     认证模块的检测方式很简单,就是判断用户的登陆 session 是否保存在服务器内存中,过期的 session 会自动清除。

     其架构如下:(图1)

网站安全认证系统的设计变迁

     阶段2:

     随着用户的增长,一台服务器已经不足以支撑时,我们开始扩展服务器,加入从1台应用服务器扩展到N(N<10)台。

     用户登陆时,通过前面 apache 的负载均衡可能随机平均访问任何一台 Tomcat。

     这时产生了一个问题,原来保存在一台应用服务器内存中的 session 数据,现在分散在不同服务器上。

     这时我们没法像上面简单的在内存中检测 session 了,为了不改动原先的程序方案,我们开始考虑 session 复制。

     还好 Tomcat 这样的应用服务器为 session 复制提供了直接支持,只需改动配置即可,而不用变动程序。

     其架构如下:(图2)

网站安全认证系统的设计变迁

     阶段3:

     用户进一步增长,应用服务器集群进一步增长,当超过10台后,session 复制开始显示出明显的低效和性能问题。

     而且单台服务器维护的 session 数据量也达到了瓶颈,我们考虑用专用的缓存服务器来取代 session 复制方案。

     memcache 或 redis 这样的缓存产品被引入作为集中式的 session 存储区域,应用服务器分离了 session 后变成了

     无状态的服务,不再受到 session 复制所需的内存和网络限制,可以进一步扩展数量。

     其架构如下:(图3)

网站安全认证系统的设计变迁

     阶段4:

     网站越来越受欢迎,用户越来越多,业务越做越广,于是开始对业务进行分类。

     应用部署上也开始按业务分类划分了不同的业务服务器集群。

     例如原本网站域名为 www.xxx.com,按业务划分集群后,我们采用子域名区分业务集群,例如 biz1.xxx.com, biz2.xxx.com。

     那么整个网站应用被划分成了各个不同的子业务系统,而所有子业务系统都需要认证授权,如何来做统一认证呢?

     这时,我们将安全认证服务也独立为一个子系统,部署在 auth.xxx.com 域名下。

     如果继续采用集中式的 session 管理,那么对每个业务子系统受保护资源的访问都需要验证 session 是否存在。

     业务子系统调用认证子系统检测用户认证信息,这样认证子系统的访问频次将很高,几乎等于全部业务子系统的 PV 总和。

     这时,认证系统的可用性将变得非常重要。

     其架构如下:(图4)

网站安全认证系统的设计变迁

     阶段5:

     为了降低业务子系统对认证系统的高可用性依赖,我们决定放弃服务端的集中式 session 管理,而采用客户端 Cookie 方式。

     当用户访问业务子系统的受保护资源时,若未登陆,则跳转到认证系统(auth.xxx.com)去进行登陆。

     登陆后认证系统写一个加密 cookie 到用户的浏览器,并跳转到用户访问的业务系统页面,浏览器自动携带这个加密 cookie 发送给业务子系统。

     业务子系统解密该 cookie 提取来自认证系统的验证和授权信息,并进行后续的业务处理。

     这里,加密的 cookie 里存储了来自认证系统授权的访问凭证(ticket),业务子系统正确解密 cookie 后获取访问凭证,即可认为用户已经过认证系统授权访问。

     其架构如下:(图5)

网站安全认证系统的设计变迁

     这个架构机制解决了业务子系统高度依赖认证系统可用性的问题,降低了认证系统的访问压力,但也有新的问题。

     这里比较明显的是,认证系统和业务子系统的互信是依赖于约定的共享密钥,密钥如何管理成为一个新的问题?

     认证系统加密 cookie 使用的密钥需要被业务子系统用来解密,如果密钥分散配置到各个业务子系统中则造成密钥分散容易泄露(降低安全性)。

     更重要的是一旦认证系统需要变更密钥则连带影响所有业务子系统,而且变更过程很难保持同步更新,导致业务子系统在更新密钥的过程中不可用的问题。

     为了提升这个架构的可用性,考虑在认证系统中包含一个密钥管理子系统,可以采用 Lease 机制来解决密钥的分布式同步和一致性问题。

     参见:Lease 机制在分布式系统中的应用

     阶段6:

     网站越做越大,后来开始并购了一些其他网站,比如 www.yyy.com。

     这时我们面临一个新问题了,需要整合多个域名下的用户统一认证。前述的 cookie 方案碰到了跨域问题。

     这里假设我们首先合并了多个站点的用户数据库,这里只需要解决基于 cookie 跨域的认证问题。

     这里提两种方式可选:

     1. 同步登录

     用户登录xxx.com同时登录yyy.com,具体做法是在 xxx.com 进行认证成功返回后携带相关的认证凭证。

     然后调用 yyy.com 的认证接口传递认证凭证,yyy.com 验证凭证后设置来自 yyy.com 的 cookie。    

     这样用户在任一站点访问受保护资源时,因为都包含了相应的 cookie 所以可以正常访问。

     流程如下:(图6)

网站安全认证系统的设计变迁

     2. 延迟登录

     与同步方式不同的是,用户登录了xxx.com时并不会立刻去请求 yyy.com 设置 cookie。

     而是等到用户真正访问 yyy.com 受保护资源时,由 yyy.com 请求统一认证中心认证后再跳转回 yyy.com 设置 cookie。

     流程如下:(图7)

网站安全认证系统的设计变迁

     两种方式仅仅是策略上的不同,从合理性上看后一种方式感觉更合理,因为毕竟用户访问了 xxx.com不代表一定要去 yyy.com。

转自:http://blog.csdn.net/mindfloating/article/details/7905093