Zabbix是一个强大的服务器/交换机监控应用,有zabbix-server, zabbix-client, zabbix-web 三部分。zabbix-web管理端是用php写的。

前文参考:CAS客户端整合(一) Discuz!

登录流程

修改代码前例行先确定登录流程

原登录过程

Zabbix的登录流程跟 Discuz 类似。系统从 cookie/session 中读取用户会话id,如果用户为 guest ,只提供部分页面访问。需要访问受限资源,需要再登录

CAS登录过程

Zabbix通过cas登录也跟Discuz几乎一样,不过这次保留了zabbix的cookie判断

代码修改

引入cas-php-client

CAS客户端路径/local/cas,新建/local/cas/CasClient.php:

phpCAS::client ( CAS_VERSION_2_0, CAS_SERVER_HOST, CAS_SERVER_PORT, CAS_SERVER_PATH );

// no SSL validation for the CAS server
phpCAS::setNoCasServerValidation ();
phpCAS::handleLogoutRequests();
/**
* 关闭url携带ticket参数,防止重复认证导致 ticket not recognized
* @see [https://www.cnblogs.com/next-door-boy/p/3372522.html]
*/
phpCAS::$_PHPCAS_CLIENT->setNoClearTicketsFromUrl ();

/include/config.inc.php中导入

// cas client
require_once dirname(__FILE__).'/../local/cas/CasClient.php';
// zabbix 核心
require_once dirname(__FILE__).'/classes/core/Z.php';

Zabbix 登录

Zabbix的用户登录验证统一接口/include/class/user/CWebUser::checkAuthentication.这里是主要的登录逻辑。zabbix从cookie中获取zbxsessionid,然后比对是否有效sessionid。如果是有效用户我们直接允许。如果是guest用户或没有 sessionid 则检查cas是否已登录,如果已登录则初始化用户信息(代码在下一步介绍)。

public static function checkAuthentication($sessionId) {
try {
if ($sessionId !== null) {
self::$data = API::User()->checkAuthentication([$sessionId]);
/*
* login as guest
* cas authentication.
*/
if (self::$data['alias'] == ZBX_GUEST_USER && phpCAS::isAuthenticated()) {
$sessionId = login_via_cas(phpCAS::getUser());
self::setSessionCookie($sessionId);
return $sessionId;
}
} if ($sessionId === null || empty(self::$data)) {
/*
* cas authentication.
*/
if (phpCAS::isAuthenticated()) {
$sessionId = login_via_cas(phpCAS::getUser());
self::setSessionCookie($sessionId);
return $sessionId;
}
self::setDefault();
self::$data = API::User()->login([
'user' => ZBX_GUEST_USER,
'password' => '',
'userData' => true
]); if (empty(self::$data)) {
clear_messages(1);
throw new Exception();
}
$sessionId = self::$data['sessionid'];
} if (self::$data['gui_access'] == GROUP_GUI_ACCESS_DISABLED) {
throw new Exception();
} self::setSessionCookie($sessionId); return $sessionId;
}
catch (Exception $e) {
self::setDefault();
return false;
}
}

初始化用户信息

根据用户名初始化用户信息,代码从/include/class/api/services/CUser::login() 方法修改而来

	/**
* Login from cas
* init user info.
* @param $name
* @author Carl
*/
function login_via_cas($name) {
$userInfo = DBfetch(DBselect(
'SELECT u.userid,u.attempt_failed,u.attempt_clock,u.attempt_ip'.
' FROM users u'.
' WHERE u.alias='.zbx_dbstr($name)
));
if (!$userInfo) {
//CUser::exception(ZBX_API_ERROR_PARAMETERS, _('Login name or password is incorrect.'));
}
// check if user is blocked
if ($userInfo['attempt_failed'] >= ZBX_LOGIN_ATTEMPTS) {
if ((time() - $userInfo['attempt_clock']) < ZBX_LOGIN_BLOCK) {
//CUser::exception(ZBX_API_ERROR_PARAMETERS, _s('Account is blocked for %s seconds', (ZBX_LOGIN_BLOCK - (time() - $userInfo['attempt_clock']))));
}
DBexecute('UPDATE users SET attempt_clock='.time().' WHERE alias='.zbx_dbstr($name));
}
// check system permissions
if (!check_perm2system($userInfo['userid'])) {
//CUser::exception(ZBX_API_ERROR_PARAMETERS, _('No permissions for system access.'));
}
$dbAccess = DBfetch(DBselect(
'SELECT MAX(g.gui_access) AS gui_access'.
' FROM usrgrp g,users_groups ug'.
' WHERE ug.userid='.zbx_dbstr($userInfo['userid']).
' AND g.usrgrpid=ug.usrgrpid'
)); if (zbx_empty($dbAccess['gui_access'])) {
$guiAccess = GROUP_GUI_ACCESS_SYSTEM;
}
else {
$guiAccess = $dbAccess['gui_access'];
}
// start session
$sessionid = md5(time().$name.rand(0, 10000000));
DBexecute('INSERT INTO sessions (sessionid,userid,lastaccess,status)'.
' VALUES ('.zbx_dbstr($sessionid).','.zbx_dbstr($userInfo['userid']).','.time().','.ZBX_SESSION_ACTIVE.')'
);
$userid = $userInfo['userid'];
$userData = DBfetch(DBselect(
'SELECT u.userid,u.alias,u.name,u.surname,u.url,u.autologin,u.autologout,u.lang,u.refresh,u.type,'.
' u.theme,u.attempt_failed,u.attempt_ip,u.attempt_clock,u.rows_per_page'.
' FROM users u'.
' WHERE u.userid='.zbx_dbstr($userid)
)); $userData['debug_mode'] = (bool) DBfetch(DBselect(
'SELECT ug.userid'.
' FROM usrgrp g,users_groups ug'.
' WHERE ug.userid='.zbx_dbstr($userid).
' AND g.usrgrpid=ug.usrgrpid'.
' AND g.debug_mode='.GROUP_DEBUG_MODE_ENABLED
)); $userData['userip'] = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'])
? $_SERVER['HTTP_X_FORWARDED_FOR']
: $_SERVER['REMOTE_ADDR'];
$userData['sessionid'] = $sessionid;
$userData['gui_access'] = $guiAccess; if ($userInfo['attempt_failed']) {
DBexecute('UPDATE users SET attempt_failed=0 WHERE userid='.zbx_dbstr($userInfo['userid']));
}
CWebUser::$data = CUser::$userData = $userData;
return $sessionid;
}

登出

分析代码发现zabbix的登出全部转到 index.php 中处理。修改logout这一段

// VAR	TYPE	OPTIONAL	FLAGS	VALIDATION	EXCEPTION
$fields = [
'name' => [T_ZBX_STR, O_NO, null, null, 'isset({enter})', _('Username')],
'password' => [T_ZBX_STR, O_OPT, null, null, 'isset({enter})'],
'sessionid' => [T_ZBX_STR, O_OPT, null, null, null],
'reconnect' => [T_ZBX_INT, O_OPT, P_SYS|P_ACT, BETWEEN(0, 65535), null],
'enter' => [T_ZBX_STR, O_OPT, P_SYS, null, null],
'autologin' => [T_ZBX_INT, O_OPT, null, null, null],
'request' => [T_ZBX_STR, O_OPT, null, null, null],
// zabbix 独特的检查机制,如果不指定无法从 $_REQUEST 变量获取获取请求参数
'logoutRequest' => [T_ZBX_STR, O_OPT, null, null, null],
];
check_fields($fields); // logout
if (isset($_REQUEST['reconnect']) || !empty($_REQUEST['logoutRequest'])) {
DBstart();
add_audit_details(AUDIT_ACTION_LOGOUT, AUDIT_RESOURCE_USER, CWebUser::$data['userid'], '', _('Manual Logout'),
CWebUser::$data['userid']
);
DBend(true);
CWebUser::logout();
//$ref = empty($_SERVER['HTTP_REFERER']) ? ('http://'.$_SERVER['SERVER_NAME'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')+1).'index.php') : $_SERVER['HTTP_REFERER'];
// cas 退出后返回的地址
$ref = 'http://'.$_SERVER['SERVER_NAME'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')+1).'index.php';
phpCAS::logoutWithRedirectService($ref);
redirect('index.php');
}

小结

代码看起来很少,但是要仔细查看源码分析登录过程,然后在什么地方做修改还是比较费心思的。

这个流程同步登录已经没问题了,但是不能同步登出。

因为zabbix的session是以cookie的形式存储。而cas-server无法清除客户端本地的cookie,这里我们又直接根据cookie验证用户,所以跳过了cas的状态复查。

这么看来,如果换成cas认证,那么必须抛弃cookie认证?

CAS客户端整合(二) Zabbix的更多相关文章

  1. CAS客户端整合(四)-- Cacti

    Cacti 是一套纯 lnmp 搭建的服务器监控系统,用 SNMP 抓取数据,RRDTool 绘制表格 登录流程 Cacti 的登录同样是先判断session,再尝试从 cookie 读取 sessi ...

  2. CAS客户端整合(三) Otrs

    OTRS 是用Perl写的一个工单邮件系统,非常强大. 登录流程 流程图略过 otrs没有像 discuz 和 zabbix 类似的游客登录状态,这样处理起来逻辑分支少一些. 不过还是考虑用 otrs ...

  3. CAS客户端整合(一) Discuz!

    有好几个系统需要接入CAS,所以登录模块统统需要重构 版本 CAS服务端是Java的 Cas-server-4.0 CAS的php客户端 是 phpCAS-1.2.0 论坛版本是 Discuz!X3. ...

  4. zabbix 二 zabbix agent 客户端

    [root@zabbix_agent src]# cd zabbix-3.0.3 [root@zabbix_agent zabbix-3.0.3]# ls aclocal.m4 bin ChangeL ...

  5. 品优购商城项目(六)CAS客户端与SpringSecurity集成

    cas单点登录旨在解决传统登录模式session在分布式项目中共享登录信息的问题. 本文cas服务器使用 4.0版本,仅供学习参考.把 cas.war 直接部署在tomcat即可,这里有个固定的用户名 ...

  6. cas sso单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas协议终极分析

    转:http://blog.csdn.net/ae6623/article/details/8848107 1)PPT流程图:ppt下载:http://pan.baidu.com/s/1o7KIlom ...

  7. window7使用svn(svn系列 客户端 知识二总结)

     ♣eclipse插件subclipse  ♣TortoiseSVN  ♣svn操作  ♣注意事项 使用svn可以在eclipse直接装subclipse或者在windows使用TortoiseSVN ...

  8. Cas 服务器 Service(Cas客户端)注册信息维护

    作为Cas服务器,允许哪些客户端接入与否是通过配置来定义的.对Cas服务器来说,每一个接入的客户端与一个Service配置对应:在Cas服务器启动时加载并注册上这些Service,与之对应的客户端才能 ...

  9. springboot之cas客户端

    一.CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源.对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 ...

随机推荐

  1. pyqt5 sip 段错误问题

    在我装labelImg工具时,装了pyqt5,而后发现缺少sip模块,又pip安装上后,启动labelImg,报段错误. 经查资料,很容易发现,是pyqt5与sip版本不匹配造成的,具体缘由,可参看: ...

  2. 16.3Sum Closest (Two-Pointers)

    Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...

  3. php模拟http请求

    在http简析中,我们提到了浏览器请求资源的一个流程,那么这个流程能不能用php来模拟呢?答案是肯定的. php模拟http请求需要实现以下步骤: 1.连接apache服务器 使用fsockopen: ...

  4. 20172325《Java程序设计》第一周学习总结

    20172325<Java程序设计>第一周学习总结 教材学习内容总结 第一章 1.1软件质量 软件工程是一门关于高质量软件开发的技术和理论的学科. 高质量软件的特征 1.2 数据结构 软件 ...

  5. $_SERVER["HTTP_HOST"]

    $_SERVER["HTTP_HOST"]访问的网站的域名

  6. JSONResult引用某博客

    http://www.cnblogs.com/JerryWang1991/archive/2013/03/08/2950457.html 最近开始用MVC做项目,在使用 JsonResult返回数据的 ...

  7. 解析config文件 练手代码

    解析一个如下的CONFIG文件 #config.txt #SHTTPD Web 服务器配置文件示例 #侦听端口 ListenPort = 80 #最大并发访问客户端数目 MaxClient = 8 # ...

  8. 一起做RGB-D SLAM(7) (完结篇)

    第七讲 添加回环检测 2016.11 更新 把原文的SIFT替换成了ORB,这样你可以在没有nonfree模块下使用本程序了. 回环检测的阈值作出了相应的调整. 请以现在的github上源码为准. 简 ...

  9. 【译】微型ORM:PetaPoco【不完整的翻译】(转)

    出处:http://www.cnblogs.com/youring2/archive/2012/06/04/2532130.html PetaPoco是一款适用于.Net 和Mono的微小.快速.单文 ...

  10. Linux安装服务器

    [实验:按照下述要求安装一台Server] /boot 100M / 10G /data 50G /var/ftp LVM 6G :/dev/vg_ftp/lv_ftp swap 2048M 主机名: ...