ldap 认证 java_Java实现LDAP认证(上)

article/2025/9/13 9:45:28

Baidu脑残,把原来的空间改得不伦不类。所以把一些技术的东西挪到这里。

我找到两种方法,大同小异,第一种是通过Spring,适合已经采用Spring的项目。

一般来说用户名和密码都是保存在数据库中。现在有这个需求,用户名和密码是保存在M$的AD中。那么如何进行认证。我找到的方法有两种,一种是jcifs,另一种是Spring Security。这里用了Spring Security,参考了CAS SSO中LDAP验证的实现。

首先建一个测试环境。在Server 2003中安装Domain,这个没啥说的,网上文章一大把。安装好以后,创建测试用的用户组(Team1)和两个用户(test,test1)。test用户属于组Team1,test1则不属于。如下图。Domain的名称是dc.testdc.com。

0818b9ca8b590ca3270a3433284dd417.png

创建好以后,在Eclipse中创建Java项目,加入以下的需要的Jar包:

0818b9ca8b590ca3270a3433284dd417.png

开始写代码。初始化部分,一些LDAP的参数设置。

static {

LdapContextSource cs = new LdapContextSource();

cs.setCacheEnvironmentProperties(false);

cs.setUrl("ldap://192.168.1.200:389");

cs.setBase("CN=Users,DC=dc,DC=testdc,DC=com");

cs.setAuthenticationSource(new AuthenticationSource() {

public String getCredentials() {

return "";

}

public String getPrincipal() {

return "CN=Administrator,CN=Users,DC=dc,DC=testdc,DC=com";

}

});

template = new LdapTemplate(cs);

}

说明。

1. 其中 ldap://192.168.1.200:389 是上面的Server 2003的地址。389是AD默认的端口,一般不用改;

2. setBase("CN=Users,DC=dc,DC=testdc,DC=com") 是查找的基础。按我自己的理解,这相当于一个查询,会查出若干结果。实际进行认证的用户必须在这些结果中。这个字符串怎么得到的呢,前面的CN=Users表明是进行用户查询;后面的DC=dc,DC=testdc,DC=com是和上面图中左上角红圈中的dc.testdc.com匹配。后面会更详细说明怎么通过Softerra LDAP Browser来帮忙取得这些值。

3. getPrincipal() 返回的是一个用户,这个用户有权限进行(2)中的查询。这里为了省事用的是Administrator,当然肯定有这个权限了。

4. getCredentials() 这里自然就是(3)中用户的密码了。

进行下一步前用Softerra LDAP Browser来确认一下上面输入的东西。

去下载安装这个东西(Free的就够用),安装有,右键,选择New:

0818b9ca8b590ca3270a3433284dd417.png

下一步,随便起个名

0818b9ca8b590ca3270a3433284dd417.png

下一步,输入AD服务器的IP,端口,点击Fetch Base DN:

0818b9ca8b590ca3270a3433284dd417.png

稍等,会出来一个列表,显示在Base DN下拉框中:

0818b9ca8b590ca3270a3433284dd417.png

这里选择的是DC=dc,DC=testDC,DC=com,下一步

0818b9ca8b590ca3270a3433284dd417.png

这里的用户名是CN=Administrator,CN=Users, DC=dc,DC=testdc,DC=com和Java代码中一致。下面的密码就填他的密码。下一步。如果有问题,会弹出错误。应该是没有错误的。

最后一步,默认的选择即可,点完成。

0818b9ca8b590ca3270a3433284dd417.png

完成后,在界面中显示了各种LDAP的对象。这里有用的是Users下面的,因为我们要对它进行认证:

0818b9ca8b590ca3270a3433284dd417.png

可以看到,Administrator和刚才创建的用户test,test1都在这里:

0818b9ca8b590ca3270a3433284dd417.png

然后继续写代码。

下面这段代码的含义,是调用LDAP的查询,查询给出的用户名/密码是否满足条件。这里说的条件,是一个Filter字符串:

final String filter = "sAMAccountName=" + username;

template.search(

new SearchExecutor() {

public NamingEnumeration executeSearch(final DirContext context) throws NamingException {

return context.search(base, filter, searchControls);

}

},

new NameClassPairCallbackHandler(){

public void handleNameClassPair(final NameClassPair nameClassPair) {

cns.add(nameClassPair.getNameInNamespace());

}

});

说明。最重要的是上面的Filter。这里用的是sAMAccountName=用户名。sAMAccountName是什么东西呢,我理解是系统中对这个用户的唯一标识。在LDAP Browser中点击一个用户,可以看到它的sAMAccountName:

0818b9ca8b590ca3270a3433284dd417.png

换句话说,上面的查询,可以这样理解。首先,我们通过Search Base的设置(setBase("CN=Users,DC=dc,DC=testdc,DC=com"))设置了查询的范围。然后上面的filter = "sAMAccountName=" + username; 设置了查询的条件。例如sAMAccountName=test的意思就是在"CN=Users,DC=dc,DC=testdc,DC=com"所表示的这么多对象中,查找sAMAccountName=test的对象。换句话说,就是查找登录的用户,在AD服务器中是否存在? 然后程序中继续判断:

if (cns.isEmpty()) {

System.out.println("Search for " + filter + " returned 0 results.");

return false;

}

if (cns.size() > 1) {

System.out.println("Search for " + filter + " returned multiple results, which is not allowed.");

return false;

}

不存在,或者多余一个存在,都是错误。返回;

for (final String dn : cns) {

DirContext test = null;

String finalDn = dn;

try {

System.out.println("Performing LDAP bind with credential: " + dn);

test = template.getContextSource().getContext(

finalDn,

password);

if (test != null) {

return true;

}

} catch (final Exception e) {

e.printStackTrace();

} finally {

if (test != null) {

test.close();

}

}

}

如果存在,并且只有一个,则获取这个用户的信息(测试用户名和密码)。如果成功,返回true。若有异常出现(比如用户存在但是密码错,或者被禁用了,返回false。

到这里基本部分的验证结束了。功能上,可以验证整个AD中存在并且合法的用户。

那么,用户组的需求怎么实现?比如只有用户组Team1中的用户可以登录?

答案是上面的Filter。上面我们用了一个最简单的Filter,filter = "sAMAccountName=" + username。自然而然,可以就可以想到更改这个Filter,让它返回"属于用户组Team1并且用户名是xxxx"的用户。写法很简单,只需要改成

final String filter = "(&(CN=" + username + ")(memberof=CN=Team1,CN=Users,DC=dc,DC=testdc,DC=com))";

即可。上面的filter,有两个条件:

1. CN=用户名

2. memberof=CN=Team1,CN=Users,DC=dc,DC=testdc,DC=com,也就是用户是(CN=Team1,CN=Users,DC=dc,DC=testdc,DC=com)的一个成员。

最前面的&表示这两个条件是相与的关系。

memberof的值是怎么来的呢,可以在LDAP Browser中查看一个Team1组中的用户,其memberof属性:

0818b9ca8b590ca3270a3433284dd417.png

在测试Filter的时候,可以在LDAP Browser中进行测试(右键New Pfofile -- 属性-- Entry页,点击Filter右侧的漏斗图标,可以在FilterBuilder

中测试)

0818b9ca8b590ca3270a3433284dd417.png

最后有个关于用户被禁用的问题。如果用户被禁用了,上面的代码会抛出一个异常,需要捕捉异常。如果不想捕捉异常,可以使用

(!(userAccountControl:1.2.840.113556.1.4.803:=2))

来过滤出所有没有被禁用的用户。

上面完整的代码放在http://一一五.com/file/be6o06r5#TestSpringLDAP.java上,需要的可以参考,建议使用前重构下,结构比较乱


http://chatgpt.dhexx.cn/article/7AZyePj3.shtml

相关文章

Harbor 整合ldap认证

前提: ldap服务器已经安装:OpenLDAP安装部署 harbor服务器已经安装:Harbro v1.8.0部署 一、ldap组织结构 1、登录信息 2、查看用户信息 二、harbor配置 1、使用默认密码登录,admin/Harbor12345 2、认证模式 3、测试ldap服务器…

ldap认证 java_Java实现LDAP认证(上) | 学步园

Baidu脑残,把原来的空间改得不伦不类。所以把一些技术的东西挪到这里。 我找到两种方法,大同小异,第一种是通过Spring,适合已经采用Spring的项目。 一般来说用户名和密码都是保存在数据库中。现在有这个需求,用户名和密…

Zabbix 整合ldap认证

前提: zabbix部署完成:CentOS7.3 64位,搭建Zabbix3.4 ldap部署完成:OpenLDAP安装部署 一、LDAP服务端 1、ldap登录信息 2、查看ldap组织架构 3、添加zabbix默认用户Admin 二、Zabbix网页端 1、使用zabbix默认管理员用户登录 …

linux+配置ldap认证,Linux LDAP 认证配置

Linux通过LDAP方式,使用windows AD帐户登录linux shell,这个想法很cool吧。之前配置过一次,但过了太久忘记了,因此,今天把配 Linux通过LDAP方式,使用windows AD帐户登录linux shell,这个想法很c…

JumpServer 整合ldap认证

前提: ldap服务器已经安装:OpenLDAP安装部署 一、JumpServer安装 官网安装地址安装部署 - JumpServer 文档 1、一键部署 #系统版本 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) #默认会安装到 /opt/jumpser…

linux samba 配置ldap认证,Samba集成Ldap认证

Samba集成Ldap认证 1.基础安装 yum -y install samba-common samba samba-client smbldap-tools openldap-clients nss-pam-ldapd 2.配置authconfig-tui 执行命令 "authconfig-tui" 验证配置 # getent passwd zhangsan:x:6460:18650:zhangsan:/home/zhangsan:/bin/…

SVN集成LDAP认证

如何将 LDAP 的认证,集成到 SVN 中。集成的办法,目前是有两种:一种是 SVN 直接通过 SVN 端口直接访问的,通过 SASL 实现 LDAP 的认证;另一种是 SVN 通过 Apache 进行 HTTP 访问的用户,通过配置 Apache &…

zabbix配置ldap认证

zabbix配置ldap认证 环境: centos6.6 zabbix3.0.3 域控服务器:windows-active server 2008 需求: 公司越来越大,人越来越多,配置人员的账号密码很麻烦。 为了集中管理,整合公司的用户密码&#xff0c…

LDAP认证-ldap介绍

OpenLDAP简介 LDAP 全称轻量级目录访问协议,是一个运行在 TCP/IP 上的目录访问协议。LDAP实现 提供被称为目录服务的信息服务,可以看做是一张特殊的数据库系统。可以有效的 解决众多网络服务的用户账户问题,规定了统一的身份信息数据库、身份…

LDAP认证

注:本文由网络公开资料整理而来,如有错误,欢迎指正。 LDAP(Lightweight Directory Access Protocol)是目录服务(DAP)在TCP/IP上的实现,它是对X.500目录协议的移植,但是简…

BlazeDS简单介绍

BlazeDS 是一个基于服务器的 Java 远程控制 (remoting) 和 Web 消息传递 (messaging) 技术,以LGPL(Lesser GNU Public License)公共许可证书发布。它能够使得后端的 Java 应用程序和运行在浏览器上的 Adobe Flex 应用程序相互通信。在Java应用…

关于BLAS的简单介绍

BLAS(Basic Linear Algebra Subprograms基础线性代数程序集)是进行向量和矩阵等基本线性代数操作的事实上的数值库。这些程序最早在1979年发布,是LAPACK(Linear Algebra PACKage)的一部分,便于建立功能更强的数值程序包。BLAS库在高性能计算中被广泛应用…

Blazor 基础入门

Blazor 基础知识 Intro Blazor 是微软在 .NET 里推出的一个 WEB 客户端 UI 交互的框架, 使用 Blazor 你可以代替 JavaScript 来实现自己的页面交互逻辑,可以很大程度上进行 C# 代码的复用,Blazor 对于 .NET 开发人员来说是一个不错的选择。 托…

Blazeds学习

BlazeDS是一个基于服务器的Java远程调用(remoting)和Web消息传递(messaging)技术,使得后台的Java应用程序和运行在浏览器上的Flex应用程序能够相互通信 一个BlazeDS应用包括两个部分:一个客户端应用程序和…

Blazeds初步

客户端应用 Blazeds包括客户端和服务端应用。客户端应用是典型的Adobe flex或者AIR应用。Flex和AIR应用使用flex组件和blazeds服务通信,包括Remote Object、HTTPService、WebService、Produce和Consumer。其中的HTTPService、WebService、Produce和Consumer是Flex S…

BlazeDS配置实例

.什么是BlazeDS BlazeDS is the server-based Java remoting and web messaging technology that enables developers to easily connect to back-end distributed data and push data in real-time to Adobe Flex and Adobe AIR™ applications for more responsive rich Inte…

Bazel

bazel:是一个可以快速构建和测试任意规模软件的编译工具,能够用来编译大部分语言。Bazel使用分布式缓存和增量构建方法,使得编译更加快速。 Bazel 主要文件 使用 Bazel 管理的项目一般包含以下几种 Bazel 相关的文件:WORKSPACE&a…

BlazeDS

BlazeDS 为使用Flex 或者AIR 的客户端程序提供了高度可扩展的远程访问和消息服务。 blazeds :是一门技术,是一门面向AS的前后台通讯框架 在服务器端:提供3种服务,远程调用(remoting-config.xml中配置),访问…

Blazeds(一)

Blazeds体系结构 一个Blazeds应用包含了一个运行在浏览器或者Adobe AIR的客户端应用并且和J2EE应用服务端通信。客户端可以是Flex也可以是结合Flex、HTML/JavaScript的应用程序。 整个体系主要包括通道、端点、消息、服务、目的地、适配器等,把这些搞懂也就…

Blazor 简介

Blazor 是一个用于使用 .NET 生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建丰富的交互式 UI。共享使用 .NET 编写的服务器端和客户端应用逻辑。将 UI 呈现为 HTML 和 CSS,以支持众多浏览器,其中包括移动浏览器。 使用 .…