You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins基于AD安全域与角色授权:用户查询脚本异常

Jenkins获取用户脚本返回非活跃/未授权用户的问题解决

我在Jenkins中使用Active Directory作为安全域,同时采用基于角色的授权机制。但执行脚本获取所有用户时,结果里既有活跃用户,也有非活跃用户,甚至出现了不在「系统管理→管理角色→分配角色」页面中的用户。执行的脚本如下:

import hudson.model.User
    User.getAll().each { user ->
        println user.getProperty(hudson.tasks.Mailer.UserProperty.class).getAddress()
    }

问题原因

User.getAll()方法获取的是Jenkins本地存储的所有用户记录——只要用户曾经登录过Jenkins(哪怕现在AD里已经禁用、或者被移除了角色权限),都会被包含进来,和AD的活跃状态、当前的角色授权无关。

解决方法

根据需求,提供几种针对性的处理方案:

方案1:只获取AD中活跃且拥有角色权限的用户

通过Active Directory插件的API直接查询AD的活跃用户,再验证用户是否有已分配的角色:

import hudson.model.User
import jenkins.model.Jenkins
import com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy
import hudson.plugins.active_directory.ActiveDirectorySecurityRealm

// 获取AD安全域实例
def adRealm = Jenkins.instance.getSecurityRealm() as ActiveDirectorySecurityRealm
// 获取角色授权策略
def authStrategy = Jenkins.instance.getAuthorizationStrategy() as RoleBasedAuthorizationStrategy

// 查询AD中的活跃用户(可根据自身AD配置调整过滤条件)
def activeAdUsers = adRealm.getDirectory().search("(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))")

activeAdUsers.each { adUser ->
    def jenkinsUser = User.get(adUser.samAccountName, false, null)
    if (jenkinsUser) {
        // 检查用户是否拥有至少一个全局或项目角色
        def hasRole = authStrategy.getRoles("global", jenkinsUser).size() > 0 || 
                      authStrategy.getRoles("project", jenkinsUser).size() > 0
        if (hasRole) {
            println jenkinsUser.getProperty(hudson.tasks.Mailer.UserProperty.class)?.getAddress()
        }
    }
}

方案2:过滤本地存储中当前有角色权限的用户

如果不需要直接查询AD,只需要从本地用户中筛选出有授权的用户:

import hudson.model.User
import jenkins.model.Jenkins
import com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy

def authStrategy = Jenkins.instance.getAuthorizationStrategy() as RoleBasedAuthorizationStrategy

User.getAll().each { user ->
    // 检查用户是否拥有全局或项目角色权限
    def hasPermission = authStrategy.getRoles("global", user).size() > 0 || 
                       authStrategy.getRoles("project", user).size() > 0
    if (hasPermission) {
        println user.getProperty(hudson.tasks.Mailer.UserProperty.class)?.getAddress()
    }
}

方案3:清理本地无效用户记录

如果想彻底移除Jenkins本地存储的非活跃/无权限用户,可以执行以下脚本(操作前建议备份Jenkins数据):

import hudson.model.User
import jenkins.model.Jenkins
import com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy
import hudson.plugins.active_directory.ActiveDirectorySecurityRealm

def adRealm = Jenkins.instance.getSecurityRealm() as ActiveDirectorySecurityRealm
def authStrategy = Jenkins.instance.getAuthorizationStrategy() as RoleBasedAuthorizationStrategy

User.getAll().each { user ->
    def username = user.getId()
    // 检查用户是否在AD中处于活跃状态
    def isAdActive = false
    try {
        def adUser = adRealm.getDirectory().findUserById(username)
        isAdActive = (adUser.userAccountControl & 2) != 2 // 2代表账户禁用
    } catch (Exception e) {
        isAdActive = false // AD中找不到用户,视为无效
    }
    // 检查用户是否有角色权限
    def hasRole = authStrategy.getRoles("global", user).size() > 0 || 
                  authStrategy.getRoles("project", user).size() > 0
    // 删除既不在AD活跃又无角色的用户
    if (!isAdActive && !hasRole) {
        println "删除无效用户: ${username}"
        user.delete()
    }
}

内容的提问来源于stack exchange,提问作者qwerty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:42:37