1
回答
用 C++ 实现基于 session 的权限管理系统
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

互联网与各种应用软件随着社会的信息化,扮演着一种越来越重要的角色,然而在竞争非常激烈的情况下,如何能够在广泛应用的基础服务之上,提供差别化 与精细化的服务,是一个企业成功的关键。针对这个问题,本文提出一种用 C++ 实现基于 session 的细粒度权限解决方案,以实现这种差别化的服务。

引言

互联网与各种应用软件随着社会的信息化,扮演着一种越来越重要的角色,然而在竞争非常激烈的情况下,如何能够在广泛应用的基础服务之上,提供 差别化与精细化的服务,是一个企业成功的关键。针对这个问题,本文提出一种用 C++ 实现基于 session 的细粒度权限解决方案,以实现这种差别化的服务。

session 介绍

常见的 session 可以分为两种 : 一个是网络 session,一个是应用程序 session。

网络 session

session 和 cookie 不同,它一般用于客户端保存用户的信息。例如,当你登录一个网站时,网站一般会把你的用户名和密码保存在计算机 C 盘一个临时文件中。当然这通常都是加密保存的,并且设置了 cookie 的有效时间,你下次访问该网站时,如果 cookie 还没失效,则不用再输入用户名和密码,就能自动登录了。而 session 用于服务器端保存用户信息。每个登录网站的用户都会在服务端分配一个 session,可以用来记录和监控用户的操作。当用户在设定的时间之内没有和服务器交互,服务器为了节省空间,会自动释放 session,下次链接需要再申请 session。

应用程序 session

应用程序 session 用于保存使用程序的客户信息以 oracle 为例,如果程序 A 连接到数据库,数据库会为 A 分配一个 session,如果分配失败,则连接失败。此 session 中保存用户的用户名、profile 等信息,并把部分信息写到 V$SESSION 系统表中,当用户退出后,session 被回收,这条记录也会被删除。

传统权限解决方案的限制

传统的权限限制是基于用户名密码和角色 (role) 级别的 (RBAC),由于 RBAC 不是本文介绍的重点,这里只举一个例子。如 Windows 操作系统中, administrator 级别的用户有权限对系统做任何应用的操作,而 gust 级别的很多功能都会受到限制了,无法查看本用户之外的人创建的文件,无法使用其他人的应用软件等,这是一种比较粗粒度的权限限制方案,如果希望对应用程序 不同操作进行权限限制,那该怎么办呢?

session 应用例子

某大型信息监控系统,启动时通过用户名和密码来登录,用户名根据 profile 进行分组,用户名和密码只在登录时进行验证 ,相同 profile 的用户权限是一样的。为了便于维护和管理,系统又分为若干个不同的子系统(subsystem)。用户在此系统上有四种操作,分别是查看(view)、提 交(submit)、确认(acknowledge)和关闭(close)信息,如表 1:


表 1. 用户操作
access_id access_name description
1 查看(view) 用户查看和自己相关的信息
2 提交(submit) 系统提交信息给用户
3 确认(acknowledge) 用户看完之后,确认信息,让系统知道用户已经看完
4 关闭(close) 关闭信息

为了对不同的操作进行不同的处理,需要创建一个操作的实体。此系统对可靠性的要求比较高,系统有正常 (Normal)、降级 (Degraded) 和委任 (Delegated) 三个状态,这三个状态的说明如下表:


表 2. 系统状态
systemState_id systemState_name description
1 正常 (Normal) 系统正常运行的状态。
2 降级 (Degraded) 系统运行时,由于某些原因没办法正常工作了,则本身变为降级状态。
3 关闭(close) 相邻节点的系统能够接管出事故的系统的工作,接管之后就是委任状态。

系统的权限和以上的每个因素都有关,super 级别的用户登录后,可以对其他用户的权限进行配置。
综上所述,实现系统的需求需要建立 profile、subsystem、access、systemState、session 五个表,其简化的类图如下:


图 1. Session 类图
图 1. Session 类图

SessionClass.GIF


清单 1. 类
				
 class session{ 
 public: 
 int requestSession(const int profile_id, const int subsystem_id, 
           const int access_id, const int systemState_id); 
 void getSessionInfo(const int session_id, int &profile_id, int &subsystem_id, 
 int &access_id, int &systemState_id); 
 void setSession(const int session_id, const int profile_id, const int subsystem_id, 
 const int access_id, const int systemState_id); 
 void endSession(); 

 private: 
 int session_id; 
 int profile_id; 
 int subsystem_id; 
 int access_id; 
 int systemState_id; 
 } 
可以使用一个专门的模块去维护和管理 session,对每个允许的操作都分配一个 session_id, 用户每做一个操作之前,便把这个操作和其他属性值传递给 session 模块,看能否获取到相应 session_id,如果可以,则能够往下操作,否则,则没有权限。这样,通过维护五个表,并且在内存中建立包含相应操作的类,实现了权限的细粒度管 理。这五个表应该有初始化的配置,并且持久化,可以保存在文件或者数据库中。

 

包含 token 的 session

  1. 以上介绍了一个用户权限规定的基本解决方案,但是在现实系统之中,为了维护数据的一致性,往往要求一个系统同时只能有一个用户对其进行操作,这个跟令牌环 网的方式很像。令牌环网出现在早期的网络中,所有的计算机组成一个环形网络,每台计算机通过一条公共的环形线路进行数据传输,如下图所示 :

图 2. Token 网络图
图 2. Token 网络图

tokenNetwork.GIF

众所周知,线路上在一个时间内只能有两台计算机进行通信,否则会发生冲突,所以引进了令牌 (token) 的概念。每个环形网只有一个令牌,想要和别的计算机通信的主机必须先获得令牌,其他主机也想获取令牌的需要等待,所以保证一条线路在同一个时间段内,只有 两台主机进行通信,但是这种网络后来逐渐以太网代替了。

  1. 参照 token 的概念,我们可以对每个系统都定义一个 token,用户对这个系统操作之前,先要获取这个 token。如果获取不到,则无法往下操作。为了保持统一,可以把 token 加到 session 之中,如果用户拥有 token,才返回用户的 session_id,否则用户无法获取到 session_id。用户使用完之后,可以调用 endSession 把 token 释放。

总结

  1. 在各式各样的系统中,用户的权限可能有很多不同的影响因素,而通过建立起这些影响因素和 session 的对应关系,可以实现不同用户中差别化的服务权限。
文章转自 IBM developerWorks
举报
IBMdW
发帖于6年前 1回/1K+阅
顶部