背景:

基于目前存在多套员工使用的日常工作子系统,现状为各系统各自有一套用户体系,员工需要记住各系统的用户名、密码等信息,还需要登录多个系统,重复工作量颇多。统一用户认证组件将用户名、密码等信息统一存储与管理,对各子系统提供统一认证接口。二期引入OpenLDAP,解决Jira、Git、Hue、CM、SVN等国外常用的开源软件不支持统一认证,而修改源码对接CUAS又成本过高的痛点。

名词解析:

Centraly User Auth Service(集中用户认证服务)以下简称CUAS;

AccessToken:访问码,默认有效期为24小时,当用户重新登录后,授权码过期。

Cectoken:跳转码,默认有效期为5分钟,当系统之间互相跳转时带上该token;

CuasToken:类似于网银的UKey,采用GoogleAuthenticator算法,30S刷新一次;

LDAP:轻量级目录访问协议,是一种广泛被遵循的协议。

二次认证:

采用GoogleAuthenticator算法,二维码生成算法结构otpauth://totp/masg?secret=3456ABCDEFGIDM。需要注意提供密钥刷新接口,当用户密钥泄露后可生成新密钥。

架构图:







关键数据库表:

用户表:T_USER

用户信息操作日志(新增、修改、修改密码): T_USER_LOG

用户密钥表(二次验证用): T_USER_SECRETKEY

用户认证日志:T_USER_AUTHLOG

Access Token表:T_USER_ACCESSTOKEN

CEC Token日志表(获取、验证):T_USER_CECTOKEN_LOG

Redis结构设计:

Redis CEC Token结构:Redis Hash结构,key=CuasService:cectoken:${cecToken}

LDAP设计

一级目录节点为dc=com,二级目录节点为dc=mzsg,不可更改;

三级目录节点定义:

用户信息节点:ou=users,存储用户及账号信息

组织信息节点:ou=organizations,存放组织信息

群组信息节点:ou=groups,存放群组信息

结构如下图:

用户信息

1.所有用户都存储在ou=users下

2.用户以uid来标识,uid为用户姓名拼音全拼,有重复时加数字

3.使用业界标准的inetOrgPerson作为基类,加入displayName、status、secAuth、companyCode、departmentCode等扩展;

组织信息

1.所有组织都存储在ou=organizations下

2.使用业界标准的organizationalUnit对象类

群组信息

1.所有群组都存储在ou=groups下

2.使用业界标准的posixGroup对象类

用户权限设计

用户组:

一个用户可以属于一到多个用户组,当用户组编码为空时为默认用户组。举例:小M是jira的管理员,在jenkins是普通用户,则小M的群组信息如下:

jira-administrators JIRA管理员

jenkins-users Jenkins普通用户

如果用户未加入jira的任何群组(jira-sofeware-users,jira-administrators),则此时用户无jira权限,无法登陆jira。

用户组设计

不是所有的第三方软件都支持userGroups的meberUid关联查找,所以还需要在用户schema上增加userGroups以对这种情况进行支持,用属性会让搜索语句变得更加简洁,当然也会增加同步维护的复杂度。

LDAP同步设计

由于需要拿到密码同步给LDAP服务器,所以用户密码需要可逆加密存储,可采用AES等对称加密。LDAP同步采用异步方式同步,即将用户修改日志T_USER_LOG按严格有序同步给LDAP服务器,如同步失败则后续跳过此用户的记录,直到问题解决。

LDAP同步编码

我用的是novell的jldap包,相比一般的JDBC操作,ldap的同步对字段要求很严格,属性值不能为空值或null值,在操作前需要先进行判断,要自行区分对属性的增、删、改操作,在增删改之前要先检查记录或属性是否存在。

OpenLDAP自定义结构

这部分网上资料较少,而且互相抄袭也比较严格,缺少一些较权威和详细的操作过程。这里鸣筝给大家一个亲测可行的步骤

1、编写schema

/etc/openldap/schema/local.schema

参考扩展mzsgCnblogsPerson结构

attributetype ( 1.1.2.1.2 NAME 'companyCode'
DESC 'company code'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.1.2.1.3 NAME 'departmentCode'
DESC 'department code'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.1.2.1.4 NAME 'status'
DESC 'status 1 means normal 0 means login forbid'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE )
attributetype ( 1.1.2.1.5 NAME 'birthday'
DESC 'birthday'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.1.2.1.6 NAME 'phone'
DESC 'phone'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.1.2.1.7 NAME 'sex'
DESC 'sex 0 means unknow 1 means male 2 means female'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE )
attributetype ( 1.1.2.1.8 NAME 'certType'
DESC 'cert type'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.1.2.1.9 NAME 'employeeNum'
DESC 'employee number'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.1.2.1.10 NAME 'certId'
DESC 'certId'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.1.2.1.11 NAME 'secAuth'
DESC 'second auth switch 0 means on 1 means off'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
SINGLE-VALUE )
attributetype ( 1.1.2.1.12 NAME 'cnName'
DESC 'cn name'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
attributetype ( 1.1.2.1.13 NAME 'userGroups'
DESC 'user groups'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
objectclass ( 1.1.2.2.2 NAME 'mzsgCnblogsPerson'
DESC 'https://www.cnblogs.com/mzsg/ person'
SUP inetOrgPerson
MUST ( status )
MAY ( companyCode $ departmentCode $ status $ birthday $ phone $ sex $ certType $ employeeNum $

2、修改sladp.conf,增加对local.schema的include

include /etc/openldap/schema/local.schema

3、编译

在/tmp下建立myConf.conf文件,添加所需依赖

include /etc/openldap/schema/core.schema

include /etc/openldap/schema/collective.schema

include /etc/openldap/schema/corba.schema

include /etc/openldap/schema/cosine.schema

include /etc/openldap/schema/duaconf.schema

include /etc/openldap/schema/inetorgperson.schema

include /etc/openldap/schema/java.schema

include /etc/openldap/schema/misc.schema

include /etc/openldap/schema/nis.schema

include /etc/openldap/schema/openldap.schema

include /etc/openldap/schema/pmi.schema

include /etc/openldap/schema/ppolicy.schema

include /etc/openldap/schema/local.schema

/etc/init.d/httpd restart

注:如果/tmp下有cn=config,则先删除。

之后运行,slapcat -f /tmp/myConf.conf -F /tmp/ -n0

把生成的的cn=config/cn=schema目录下对应的ldif文件去替换ldap中原先cn=config/cn=schema中的ldif文件。

位置在:/etc/ldap/slapd.d/cn=config/cn=schema

注意有时phpLdapAdmin会显示自定义Schema报错,JXplorer能正常支持

cd /etc/openldap/slapd.d/cn=config/cn=schema

rm -rf *

cp /tmp/cn=config/cn=schema/* .

chmod 777 *

注意,要先删除,再加,否则容易有重复定义的问题

接入LDAP

在git、svn、jenkins、jira、confluence、Kibana接入LDAP的过程中,注意事项有

在接入git之前必须保证用户信息中的email信息齐全并与历史git中的用户的邮箱一致,否则需做相应修改,相同用户名邮箱名不同的记录用户名会被自动修改,我就在这里花了挺长的时间。SVN接入时,使用SASL进行用户验证,svn的用户管理还是要在authz中管理,相当于加SVN的用户需要在CUAS和SVN的服务器authz中分别新增。

几点思考

1、为什么不去掉Mysql,改为使用OpenLDAP存储?

OpenLDAP更适合写少读多的场景,OpenLDAP不支持事务。最为重要的是我们在关系型数据库上具有丰富的经验,万一在OpenLDAP中的数据被玩坏了,我们可以轻松地从Mysql中同步恢复过来。

2、为什么LDAP服务器用的是OpenLDAP?

LDAP比较知名的开源实现是OpenLDAP和ApacheDS,两者都是优秀的产品。相比之下,前者在网络上的文档资料更多,也更轻量。

3、为什么不采用CAS而自行建设CUAS?

由于公司内部存在不少遗留系统,如果引入CAS需进行大量定制和裁减以减少各系统的集成难度和减少推行压力,而CUAS灵活定制化后结合公司内部的研发框架,可大大减少集成复杂度。

4、LDAP设计为什么要采用用户、组织、群组指定DN,为什么用户不挂在组织下形成严格的树状结构?

严格的树状结构会导致组织和用户的维护严重耦合,另外扁平的结构更方便条件查找。

效果

各业务系统管理后台通过统一门户进行统一认证后进行单点登陆。git、svn、jenkins、jira、confluence、Kibana以ldap进行统一认证。员工离职只需要在统一门户进行操作,所有系统均不可登录。员工入职通过统一门户进行录入可同步给各业务系统并分配最低权限(实施中),通过用户组,由各系统自行映射用户组对应的权限列表。该实现方式的不足是CUAS只管到用户组,权限仍散落到各业务系统各自管理。

好了,如果你对企业统一用户认证系统建设或LDAP有其它疑问,可在评论区讨论。如果你有关于企业统一用户认证系统建设或LDAP的开发、培训或咨询需求,也请站内信联系我。

统一用户认证系统CUAS实现要点的更多相关文章

  1. 基于DDD + SD.Framework实现的统一身份认证系统

    项目地址 http://git.oschina.net/lishilei0523/ShSoft.UAC 项目说明 本项目开发的目的有三: 1.作为一个使用SD.Framework框架开发的项目样板 2 ...

  2. django用户认证系统——拓展 User 模型

    Django 用户认证系统提供了一个内置的 User 对象,用于记录用户的用户名,密码等个人信息.对于 Django 内置的 User 模型, 仅包含以下一些主要的属性: username,即用户名 ...

  3. “Django用户认证系统”学习资料收集

    首推追梦人物——Django用户认证系统 待续……

  4. 中国科学技术大学统一身份认证系统CAS

    CAS | Apereohttps://www.apereo.org/projects/cas 中国科学技术大学统一身份认证系统https://passport.ustc.edu.cn/login?s ...

  5. Django Authentication 用户认证系统

    一. Django的认证系统 Django自带一个用户认证系统,用于处理用户账户.群组.许可和基于cookie的用户会话. 1.1 概览 Django的认证系统包含了身份验证和权限管理两部分.简单地说 ...

  6. django用户认证系统——重置密码7

    当用户不小心忘记了密码时,网站需要提供让用户找回账户密码的功能.在示例项目中,我们将发送一封含有重置用户密码链接的邮件到用户注册时的邮箱,用户点击收到的链接就可以重置他的密码,下面是具体做法. 发送邮 ...

  7. django用户认证系统——修改密码6

    再此之前我们已经完成了用户登录.注册.注销等功能,接下来让我们继续为用户提供修改密码的功能.该功能 Django 的 auth 应用也已经为我们提供,过程几乎和之前的登录功能完全一样. 编写修改密码模 ...

  8. django用户认证系统——登录4

    用户已经能够在我们的网站注册了,注册就是为了登录,接下来我们为用户提供登录功能.和注册不同的是,Django 已经为我们写好了登录功能的全部代码,我们不必像之前处理注册流程那样费劲了.只需几分钟的简单 ...

  9. django用户认证系统——拓展 User 模型2

    Django 用户认证系统提供了一个内置的 User 对象,用于记录用户的用户名,密码等个人信息.对于 Django 内置的 User 模型, 仅包含以下一些主要的属性: username,即用户名 ...

随机推荐

  1. Django - ORM - 事务, 乐观锁, 悲观锁

    事务 概念 Transaction 事务:一个最小的不可再分的工作单元:通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元) 一个完整的业务需要批量的DML(inser ...

  2. python之Anaconda python3.7安装

    1.下载 https://www.anaconda.com/distribution/ #你会发现,使用windows下载十分慢,既然这样,为何不尝试centos(linux)安装呢?本人使用cent ...

  3. 009-DNS域名解析系统

    一.概述 DNS是域名系统(DomainNameSystem)的缩写,该系统用于命名组织到域层次结构中的计算机和网络服务.域名是由圆点分开一串单词或缩写组成的,每一个域名都对应一个惟一的IP地址,在I ...

  4. set serveroutput on

    使用set serveroutput on 命令设置环境变量serveroutput为打开状态,从而使得pl/sql程序能够在SQL*plus中输出结果 使用函数dbms_output.put_lin ...

  5. linux rz sz替代方案

    SFTP是基于SSH的文件传输协议,与ZMODEM相比具有更加安全且更为快速的文件传输功能. 如何利用SFTP接收文件: 1. 在本地提示以sftp命令登陆拟要接收文件的主机.Xshell:\> ...

  6. 使用 bash 脚本把 GCE 的数据备份到 GCS

    目录 一.Google Cloud Storge 介绍 1.1.四种存储类别的比较 1.2.需求 1.3.给虚拟机添加授权认证 二.备份操作 2.1 创建存储分区 2.2 上传对象到存储分区 2.3 ...

  7. 源码搭建zabbix服务

    1) 部署LNMP 1.1) cd /root tar -xf lnmp_soft.tar.gz cd lnmp_soft/ tar -xf nginx-1.10.3.tar.gz cd nginx- ...

  8. Ubuntu14.04LTS 下配置Tomcat Hadoop eclipse环境

    下在相关软件: (genju yingjian xuanze xitong weishu,根据系统是32位还是64位选择软件的版本:jdk和eclipse) HADOOP:http://mirrors ...

  9. HIVE配置mysql metastore

    HIVE配置mysql metastore    hive中除了保存真正的数据以外还要额外保存用来描述库.表.数据的数据,称为hive的元数据.这些元数据又存放在何处呢?    如果不修改配置hive ...

  10. kafka consumer 的配置(五)

    fetch.min.bytes. #获取最小字节数据 Consumer 向broker中要数据时是按大小来返回的,如果数据没有达到指定的MB,consumer会处于等待状态,直到broker 从pro ...