java连接kerberos用户认证

news2025/1/14 2:24:49

在这里插入图片描述

文章目录

  • 一、背景
  • 二、代码
    • 2.1目录
    • 2.2配置文件application.properties
    • 2.3pom依赖
    • 2.4代码
      • AuthProviderConfig配置类
      • CustomConfigurationByKeytab配置类
      • CustomConfigurationByPassword配置类
      • TestController
      • MyCallbackHandler
      • DummyUserDetailsService实现类
      • LdapTest2Application启动类
      • KerberosTest测试类
      • SpringVersionUtils测试类
  • 三、可能碰到的报错
    • 错误场景1:javax.security.auth.login.LoginException: Receive timed out
    • 错误场景2:javax.security.auth.login.LoginException: Cannot locate KDC
    • 错误场景3:javax.security.auth.login.LoginException: No CallbackHandler available to garner authentication information from the user
    • 错误场景4:javax.security.auth.login.LoginException: Checksum failed
    • 错误场景5:javax.security.auth.login.LoginException: Message stream modified (41)
    • 错误场景6:javax.security.auth.login.LoginException: null (68)
    • 错误场景7:javax.security.auth.login.LoginException: Unable to obtain password from user
  • 五、认证成功的结果打印
    • 通过输入用户+keytab方式认证成功打印
    • 通过输入用户+密码方式认证成功打印
  • 六、其他报错可参考文档
  • 本人其他相关文章链接

一、背景

亲测可用,之前搜索了很多博客,啥样的都有,就是不介绍报错以及配置用处,根本不懂照抄那些配置是干啥的,稀里糊涂的按照博客搭完也跑不起来,因此记录这个。

项目背景:公司项目当前采用http协议+shiro+mysql的登录认证方式,而现在想支持ldap协议认证登录然后能够访问自己公司的项目网站。

举例说明:假设我们公司有自己的门户网站,现在我们收购了一家公司,他们数据库采用ldap存储用户数据,那么为了他们账户能登陆我们公司项目所以需要集成,而不是再把他们的账户重新在mysql再创建一遍,万一人家有1W个账户呢,不累死了且也不现实啊。

需要安装openldap+kerberos,且ldap和kerberos安装在同一台服务器上,当前版本如下:

  • centos 7.9
  • openldap 2.4.44
  • phpldapadmin 1.2.5
  • 服务器IP:10.110.38.162
  • Kerberos :Kerberos 5 release 1.15.1

另外介绍下我的Spring各个版本:

  • Spring Security:4.2.3.RELEASE
  • Spring Version:4.3.9.RELEASE
  • SpringBoot Version:1.4.7.RELEASE

注意点1:我之所以选这么旧的版本,是因为我最后要在自己项目集成,我们项目就是上面版本附近的,所以不能选太高版本,这点请注意各版本之间的兼容性问题。
详情可看这篇博客介绍兼容版本:https://zhuanlan.zhihu.com/p/652895555

注意点2:如果里面的某些配置不知道在哪或者不知道干啥的,可以看我的前面的博客,详细介绍了安装配置等,可以大致了解参数。

目前网上相关文章很少,而且好多博客都是未认证就发布的所以一堆问题,跑不起来,如下是我参考的博客

  • Spring Security Kerberos - Reference Documentation
  • MIT Kerberos Documentation
  • https://www.openldap.org/
  • Authentication Protocols: LDAP vs Kerberos vs OAuth2 vs SAML vs RADIUS

二、代码

2.1目录

在这里插入图片描述

2.2配置文件application.properties

server.port=8020

2.3pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>1.4.7.RELEASE</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>ldap-test2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ldap-test2</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--解决@RestController注解爆红-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <!--测试类-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-security-core</artifactId>
                    <groupId>org.springframework.security</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-ldap</artifactId>
            <version>2.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-ldap</artifactId>
            <version>2.6.3</version>
        </dependency>
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>ldapbp</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.ldap</groupId>
            <artifactId>spring-ldap-core</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.directory.api</groupId>
            <artifactId>api-all</artifactId>
            <version>2.0.0</version>
        </dependency>

        <!-- Spring Security Kerberos -->
        <dependency>
            <groupId>org.springframework.security.kerberos</groupId>
            <artifactId>spring-security-kerberos-core</artifactId>
            <version>1.0.1.RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>spring-security-core</artifactId>
                    <groupId>org.springframework.security</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.kerberos</groupId>
            <artifactId>spring-security-kerberos-client</artifactId>
            <version>1.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.kerberos</groupId>
            <artifactId>spring-security-kerberos-web</artifactId>
            <version>1.0.1.RELEASE</version>
        </dependency>

        <!-- Additional dependencies for Spring LDAP and Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-ldap</artifactId>
            <version>4.2.3.RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>spring-security-core</artifactId>
                    <groupId>org.springframework.security</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>4.2.3.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.example.ldaptest2.LdapTest2Application</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.4代码

AuthProviderConfig配置类

说明:注释的代码还没放开,目前只是demo阶段,后续需要集成到自己项目 ,肯定需要配置哪些路径访问权限放开,如果没权限自动跳转项目登录页等等,后续需要再配置的。

package com.example.ldaptest2.config;

import com.example.ldaptest2.service.DummyUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.kerberos.authentication.KerberosAuthenticationProvider;
import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosClient;

@Configuration
@EnableWebMvcSecurity
public class AuthProviderConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/ldap/*").permitAll()
            .anyRequest().authenticated();
//            .and()
//            .formLogin()
//            .loginPage("/login").permitAll()
//            .and()
//            .logout()
//            .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(kerberosAuthenticationProvider());
    }

    @Bean
    public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
        KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
        SunJaasKerberosClient client = new SunJaasKerberosClient();
        client.setDebug(true);
        provider.setKerberosClient(client);
        provider.setUserDetailsService(dummyUserDetailsService());
        return provider;
    }

    @Bean
    public DummyUserDetailsService dummyUserDetailsService() {
        return new DummyUserDetailsService();
    }

}

CustomConfigurationByKeytab配置类

package com.example.ldaptest2.config;

import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author 211145187
 * @Date 2024/6/13 16:34
 **/
// 自定义 Configuration 类,用于提供 Kerberos 登录配置
public class CustomConfigurationByKeytab extends Configuration {
    @Override
    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
        if ("KrbLogin".equals(name)) {
            Map<String, String> options = new HashMap<>();
            options.put("useKeyTab", "true");   //指定是否使用 keytab 文件进行登录,这里设置为 true,表示使用 keytab 文件。
            options.put("keyTab", "C:\\Users\\211145187\\Desktop\\fsdownload\\ldap.keytab"); //指定 keytab 文件的路径,这里设置为 "/etc/openldap/ldap.keytab"。
//            options.put("keyTab", "/etc/openldap/ldap.keytab"); //指定 keytab 文件的路径,这里设置为 "/etc/openldap/ldap.keytab"。
            options.put("storeKey", "true");    //指定是否将密钥存储在 Subject 中,这里设置为 true,表示存储密钥。
            options.put("useTicketCache", "false"); //指定是否使用票据缓存,这里设置为 false,表示不使用票据缓存。
            options.put("doNotPrompt", "true"); //指定是否禁止提示用户输入用户名和密码,这里设置为 true,表示禁止提示。
            options.put("debug", "true");   //指定是否启用调试模式,这里设置为 true,表示启用调试模式。
            options.put("principal", "ldapadmin@NODE3.COM"); //指定要使用的主体名称,这里设置为 "ldap/bridge1@NODE3.COM",表示使用的服务主体。

            // 定义 Kerberos 登录模块的配置项
            AppConfigurationEntry entry = new AppConfigurationEntry(
                    "com.sun.security.auth.module.Krb5LoginModule",
                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
                    options
            );
            return new AppConfigurationEntry[]{entry};
        }
        return null;
    }
}

CustomConfigurationByPassword配置类

package com.example.ldaptest2.config;

import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author 211145187
 * @Date 2024/6/13 16:34
 **/
// 自定义 Configuration 类,用于提供 Kerberos 登录配置
public class CustomConfigurationByPassword extends Configuration {
    @Override
    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
        if ("KrbLogin".equals(name)) {
            Map<String, String> options = new HashMap<>();
            options.put("useKeyTab", "false");   //指定是否使用 keytab 文件进行登录,这里设置为 true,表示使用 keytab 文件。
            options.put("storeKey", "true");    //指定是否将密钥存储在 Subject 中,这里设置为 true,表示存储密钥。
            options.put("useTicketCache", "false"); //指定是否使用票据缓存,这里设置为 false,表示不使用票据缓存。
            options.put("doNotPrompt", "false"); //指定是否禁止提示用户输入用户名和密码,这里设置为 true,表示禁止提示。
            options.put("debug", "true");   //指定是否启用调试模式,这里设置为 true,表示启用调试模式。
            options.put("password", "123456"); //指定要使用的主体名称,这里设置为 "ldap/bridge1@NODE3.COM",表示使用的服务主体。
            options.put("principal", "testldap3@NODE3.COM"); //指定要使用的主体名称,这里设置为 "ldap/bridge1@NODE3.COM",表示使用的服务主体。

            // 定义 Kerberos 登录模块的配置项
            AppConfigurationEntry entry = new AppConfigurationEntry(
                    "com.sun.security.auth.module.Krb5LoginModule",
                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
                    options
            );
            return new AppConfigurationEntry[]{entry};
        }
        return null;
    }
}

TestController

注意:其实这个controller可有可无,因为你写java客户端连接kerberos,如果不涉及打包部署linux环境通过url方式掉方法,完全可以不写这个,只写本地测试方法即可。

package com.example.ldaptest2.controller;

import com.example.ldaptest2.config.CustomConfigurationByKeytab;
import com.example.ldaptest2.config.CustomConfigurationByPassword;
import com.example.ldaptest2.entity.LdapUser;
import com.example.ldaptest2.entity.MyCallbackHandler;
import com.example.ldaptest2.mapper.LdapUserAttributeMapper;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
 * @Author 211145187
 * @Date 2024/6/14 17:18
 **/
@RestController
@RequestMapping("/ldap")
public class TestController {
    private static Logger logger = LoggerFactory.getLogger(TestController.class);

    //keytab认证
    @GetMapping(value = "/authenticateUserByKeytab")
    public void authenticateUserByKeytab() {
        try {
            System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
            // 创建 LoginContext 对象,并为其提供自定义 Configuration
            LoginContext lc = new LoginContext("KrbLogin", null, null, new CustomConfigurationByKeytab());

            // 进行 Kerberos 认证
            lc.login();
            // 获取 Subject
            Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
            // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
            // 登出
            lc.logout();
        } catch (LoginException e) {
            // 处理登录异常
            e.printStackTrace();
            logger.error("LoginException e:{}", e.getMessage());
        }
    }

    //用户+密码认证
    @GetMapping(value = "/authenticateUserByPassword")
    public void authenticateUserByPassword() {
        try {
            System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
            // 创建 LoginContext 对象,并为其提供自定义 Configuration
            LoginContext lc = new LoginContext("KrbLogin", null, new MyCallbackHandler(), new CustomConfigurationByPassword());

            // 进行 Kerberos 认证
            lc.login();
            // 获取 Subject
            Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
            // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
            // 登出
            lc.logout();
        } catch (LoginException e) {
            // 处理登录异常
            e.printStackTrace();
            logger.error("LoginException e:{}", e.getMessage());
        }
    }

    @GetMapping(value = "/test")
    public String test() {
        return "Hello";
    }    
}

MyCallbackHandler

package com.example.ldaptest2.entity;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

/**
 * @Author 211145187
 * @Date 2024/6/13 19:18
 **/
public class MyCallbackHandler implements CallbackHandler {
    @Override
    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof NameCallback) {
                // 处理用户名回调
                NameCallback nc = (NameCallback) callback;
                nc.setName("ldapadmin@NODE3.COM"); // 设置用户名
            } else if (callback instanceof PasswordCallback) {
                // 处理密码回调
                PasswordCallback pc = (PasswordCallback) callback;
                pc.setPassword("123456".toCharArray()); // 设置密码
            } else {
                throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
                // 其他类型的回调
                // 可以根据需要处理其他类型的回调
            }
        }
    }
}

DummyUserDetailsService实现类

package com.example.ldaptest2.service;

import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * @Author 211145187
 * @Date 2024/6/13 15:37
 **/
public class DummyUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new User(username, "notUsed", true, true, true, true,
                AuthorityUtils.createAuthorityList("ROLE_USER"));
    }

}

LdapTest2Application启动类

package com.example.ldaptest2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class LdapTest2Application {

    public static void main(String[] args) {
        SpringApplication.run(LdapTest2Application.class, args);
    }
}

KerberosTest测试类

package com.example.ldaptest2;

import com.example.ldaptest2.config.CustomConfigurationByKeytab;
import com.example.ldaptest2.config.CustomConfigurationByPassword;
import com.example.ldaptest2.entity.MyCallbackHandler;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

@SpringBootTest
@RunWith(SpringRunner.class)
public class KerberosTest {
    private static Logger logger = LoggerFactory.getLogger(KerberosTest.class);

    //用户+密码认证
    @Test
    public void authenticateUserByPassword() {
        try {
            System.setProperty("java.security.krb5.conf", "C:\\Users\\211145187\\Desktop\\fsdownload\\krb5.conf");
            // 创建 LoginContext 对象,并为其提供自定义 Configuration
            LoginContext lc = new LoginContext("KrbLogin", null, new MyCallbackHandler(), new CustomConfigurationByPassword());

            // 进行 Kerberos 认证
            lc.login();
            // 获取 Subject
            Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
            // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
            // 登出
            lc.logout();
        } catch (LoginException e) {
            // 处理登录异常
            e.printStackTrace();
        }
    }

    //keytab认证
    @Test
    public void authenticateUserByKeytab() {
        try {
            System.setProperty("java.security.krb5.conf", "C:\\Users\\211145187\\Desktop\\fsdownload\\krb5.conf");
            // 创建 LoginContext 对象,并为其提供自定义 Configuration
            LoginContext lc = new LoginContext("KrbLogin", null, null, new CustomConfigurationByKeytab());

            // 进行 Kerberos 认证
            lc.login();
            // 获取 Subject
            Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
            // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
            // 登出
            lc.logout();
        } catch (LoginException e) {
            // 处理登录异常
            e.printStackTrace();
        }
    }
}

SpringVersionUtils测试类

package com.example.ldaptest2;

import org.junit.Test;
import org.springframework.boot.SpringBootVersion;
import org.springframework.core.SpringVersion;
import org.springframework.security.core.SpringSecurityCoreVersion;

/**
 * 获取Spring、SpringBoot版本号
 * @Author 211145187
 * @Date 2022/11/12 10:42
 **/
public class SpringVersionUtils {

    /**
     * Spring Security:4.2.3.RELEASE
     * Spring Version:4.3.9.RELEASE
     * SpringBoot Version:1.4.7.RELEASE
     */
    @Test
    public void getSpringVersion() {
        System.out.println("Spring Security:" + SpringSecurityCoreVersion.getVersion());
        String versionSpring = SpringVersion.getVersion();
        String versionSpringBoot = SpringBootVersion.getVersion();
        System.out.println("Spring Version:" + versionSpring);
        System.out.println("SpringBoot Version:" + versionSpringBoot);
    }

}

三、可能碰到的报错

错误场景1:javax.security.auth.login.LoginException: Receive timed out

完整错误

Receive timed out
javax.security.auth.login.LoginException: Receive timed out
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:812)
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:618)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
        at com.example.ldaptest2.controller.TestController.authenticateUserByPassword(TestController.java:78)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketTimeoutException: Receive timed out
        at java.net.PlainDatagramSocketImpl.receive0(Native Method)
        at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:143)
        at java.net.DatagramSocket.receive(DatagramSocket.java:812)
        at sun.security.krb5.internal.UDPClient.receive(NetClient.java:206)
        at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:404)
        at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:364)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.security.krb5.KdcComm.send(KdcComm.java:348)
        at sun.security.krb5.KdcComm.sendIfPossible(KdcComm.java:253)
        at sun.security.krb5.KdcComm.send(KdcComm.java:229)
        at sun.security.krb5.KdcComm.send(KdcComm.java:200)
        at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:343)
        at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:447)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:770)
        ... 100 more

我的代码

@GetMapping(value = "/authenticateUserByPassword")
public void authenticateUserByPassword() {
     try {
         System.setProperty("java.security.krb5.conf", "/temporary/krb5.conf");
         // 创建 LoginContext 对象,并为其提供自定义 Configuration
         LoginContext lc = new LoginContext("KrbLogin", null, new MyCallbackHandler(), new CustomConfigurationByPassword());

         // 进行 Kerberos 认证
         lc.login();
         // 获取 Subject
         Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
         // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
         // 登出
         lc.logout();
     } catch (LoginException e) {
         // 处理登录异常
         e.printStackTrace();
         logger.error("LoginException e:{}", e.getMessage());
     }
 }

查看38.162服务器上/var/log/krb5kdc.log日志,看详细报错:

otp: Loaded
Jun 17 14:51:41 localhost.localdomain krb5kdc[6531](info): setting up network...
krb5kdc: setsockopt(12,IPV6_V6ONLY,1) worked
krb5kdc: setsockopt(14,IPV6_V6ONLY,1) worked
Jun 17 14:51:41 localhost.localdomain krb5kdc[6531](info): set up 4 sockets
Jun 17 14:51:41 localhost.localdomain krb5kdc[6533](info): commencing operation
Jun 17 14:52:01 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 127.0.0.1: CLIENT_NOT_FOUND: ldap/admin@NODE3.COM for kadmin/127.0.0.1@NODE3.COM, Client not found in Kerberos database
Jun 17 14:57:22 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 127.0.0.1: CLIENT_NOT_FOUND: ldap/admin@NODE3.COM for kadmin/127.0.0.1@NODE3.COM, Client not found in Kerberos database
Jun 18 01:44:05 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: CLIENT_NOT_FOUND: ldap/bridge1@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM, Client not found in Kerberos database
Jun 18 01:44:05 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: CLIENT_NOT_FOUND: ldap/bridge1@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM, Client not found in Kerberos database
Jun 18 07:25:44 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 16 23 25 26 20 19}) 127.0.0.1: ISSUE: authtime 1718666744, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 07:29:04 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718666944, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 09:21:25 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718673685, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 11:10:13 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718680213, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 11:16:22 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718680582, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 11:17:08 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 127.0.0.1: ISSUE: authtime 1718680628, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 11:17:20 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 127.0.0.1: ISSUE: authtime 1718680640, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 11:17:26 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 127.0.0.1: ISSUE: authtime 1718680646, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 11:18:33 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 127.0.0.1: ISSUE: authtime 1718680713, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 18 11:18:44 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718680724, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:37:41 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718739461, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:38:42 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 16 23 25 26 20 19}) 127.0.0.1: ISSUE: authtime 1718739522, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:41:16 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 16 23 25 26 20 19}) 127.0.0.1: ISSUE: authtime 1718739676, etypes {rep=18 tkt=18 ses=18}, ldap/bridge1@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:41:22 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 16 23 25 26 20 19}) 127.0.0.1: ISSUE: authtime 1718739682, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:41:59 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 16 23 25 26 20 19}) 127.0.0.1: ISSUE: authtime 1718739719, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:51:21 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 127.0.0.1: ISSUE: authtime 1718740281, etypes {rep=18 tkt=18 ses=18}, testldap3@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:51:36 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 16 23 25 26 20 19}) 127.0.0.1: ISSUE: authtime 1718740296, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:53:15 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718740395, etypes {rep=18 tkt=18 ses=18}, ldapadmin@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:53:55 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718740435, etypes {rep=18 tkt=18 ses=18}, testldap3@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:55:13 localhost.localdomain krb5kdc[6533](info): AS_REQ (4 etypes {18 17 16 23}) 127.0.0.1: ISSUE: authtime 1718740513, etypes {rep=18 tkt=18 ses=18}, testldap3@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM
Jun 19 03:58:19 localhost.localdomain krb5kdc[6533](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 127.0.0.1: CLIENT_NOT_FOUND: ldaptest3@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM, Client not found in Kerberos database
Jun 19 05:27:53 localhost.localdomain krb5kdc[6533](info): closing down fd 14
Jun 19 05:27:53 localhost.localdomain krb5kdc[6533](info): closing down fd 13
Jun 19 05:27:53 localhost.localdomain krb5kdc[6533](info): closing down fd 12
Jun 19 05:27:53 localhost.localdomain krb5kdc[6533](info): closing down fd 11
Jun 19 05:27:53 localhost.localdomain krb5kdc[6533](info): shutting down

场景描述:我把demo项目打包运行在209服务器,而ldap+kerberos安装在38.162服务器上,进行接口联调。

错误原因

主要看这行:CLIENT_NOT_FOUND: ldaptest3@NODE3.COM for krbtgt/NODE3.COM@NODE3.COM, Client not found in Kerberos database

再看这行:javax.security.auth.login.LoginException: Receive timed out

报错显示javax.security.auth.login.LoginException: Receive timed out,总感觉代码没连接kerberos,或者说感觉java代码客户端对面kerberos不认识。
之前我是demo运行在38.162就能认证应该是能识别,当我把demo放在209服务器上就报错了
猜测可能是209服务器的连接不上38.162的88端口,所以应该是网络的问题

举例说明

举例说明:56.70服务器运行telnet 命令查看88端口是否可用

[root@localhost temporary]# telnet 10.110.38.162 88
Trying 10.110.38.162...
Connected to 10.110.38.162.
Escape character is '^]'.

209运行telnet 命令查看88端口是否可用

[root@localhost temporary]#  telnet 10.110.38.162 88
Trying 10.110.38.162...
telnet: connect to address 10.110.38.162: Connection timed out
[root@localhost temporary]# 

解决方案:你换台服务器跑项目就能调通了。

错误场景2:javax.security.auth.login.LoginException: Cannot locate KDC

完整错误

Cannot locate KDC
javax.security.auth.login.LoginException: Cannot locate KDC
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:808)
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:618)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
        at com.example.ldaptest2.controller.TestController.authenticateUserByPassword(TestController.java:77)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
Caused by: KrbException: Cannot locate KDC
        at sun.security.krb5.Config.getKDCList(Config.java:1189)
        at sun.security.krb5.KdcComm.send(KdcComm.java:218)
        at sun.security.krb5.KdcComm.send(KdcComm.java:200)
        at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:343)
        at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:447)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:770)
        ... 100 more
Caused by: KrbException: Generic error (description in e-text) (60) - Unable to locate KDC for realm NODE3.COM
        at sun.security.krb5.Config.getKDCFromDNS(Config.java:1286)
        at sun.security.krb5.Config.getKDCList(Config.java:1162)

错误代码

//用户+密码认证
@Test
public void authenticateUserByPassword() {
    try {
        // 创建 LoginContext 对象,并为其提供自定义 Configuration
        LoginContext lc = new LoginContext("KrbLogin", null, new MyCallbackHandler(), new CustomConfigurationByPassword());

        // 进行 Kerberos 认证
        lc.login();
        // 获取 Subject
        Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
        // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
        // 登出
        lc.logout();
    } catch (LoginException e) {
        // 处理登录异常
        e.printStackTrace();
    }
}

场景描述:windows本地跑项目,我的ldap+kerberos安装在38.162环境,我想本地windows上连接38.162服务器进行kerberos用户认证。

错误原因:没有注入配置文件,人家代码凭啥能精准找到38.162服务器上,你得导入配置文件啊,因为你的项目中只有ldap服务的一些配置,压根kerberos的相关配置,且代码中只引入CustomConfigurationByPassword,里面压根没有指定IP啥的地方。

解决方案:设置:System.setProperty(“java.security.krb5.conf”, “/xxx/krb5.conf”);

正确代码:

//用户+密码认证
@Test
public void authenticateUserByPassword() {
    try {
        System.setProperty("java.security.krb5.conf", "C:\\Users\\211145187\\Desktop\\fsdownload\\krb5.conf");
        // 创建 LoginContext 对象,并为其提供自定义 Configuration
        LoginContext lc = new LoginContext("KrbLogin", null, new MyCallbackHandler(), new CustomConfigurationByPassword());

        // 进行 Kerberos 认证
        lc.login();
        // 获取 Subject
        Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
        // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
        // 登出
        lc.logout();
    } catch (LoginException e) {
        // 处理登录异常
        e.printStackTrace();
    }
}

思路讲解:首先把配置文件krb5.conf下载下来,然后当你代码注入System.setProperty配置文件的时候,项目就会读取配置文件内容,其中的kdc就配置了10.110.38.162,所以项目代码就知道连接到哪里进行kerberos认证了。

krb5.conf

# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 dns_lookup_realm = false
 ticket_lifetime = 24h
 #renew_lifetime = 7d
 forwardable = true
 rdns = false
 pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
 default_realm = NODE3.COM
# default_ccache_name = KEYRING:persistent:%{uid}

[realms]
 NODE3.COM = {
 # kdc = kdc.node.com
 # admin_server = kdc.node.com
  kdc = 10.110.38.162
  admin_server = 10.110.38.162
  ldap_servers = ldap://10.110.38.162:389

 # kdc = node3.com:88
 # admin_server = node3.com:749
 # default_domain = NODE3.COM
 }

[domain_realm]
 .node3.com = NODE3.COM
 node3.com = NODE3.COM

错误场景3:javax.security.auth.login.LoginException: No CallbackHandler available to garner authentication information from the user

完整错误

Debug is  true storeKey true useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is ldapadmin@NODE3.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
                [Krb5LoginModule] authentication failed 
No CallbackHandler available to garner authentication information from the user
javax.security.auth.login.LoginException: No CallbackHandler available to garner authentication information from the user
        at com.sun.security.auth.module.Krb5LoginModule.promptForPass(Krb5LoginModule.java:905)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:764)
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:618)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
        at com.example.ldaptest2.controller.TestController.authenticateUserByPassword(TestController.java:65)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
2024-06-18 09:25:45.137 ERROR 15510 --- [nio-8020-exec-1] c.e.ldaptest2.controller.TestController  : LoginException e:No CallbackHandler available to garner authentication information from the user

错误代码:

//用户+密码认证
@Test
public void authenticateUserByPassword() {
    try {
        System.setProperty("java.security.krb5.conf", "C:\\Users\\211145187\\Desktop\\fsdownload\\krb5.conf");
        // 创建 LoginContext 对象,并为其提供自定义 Configuration
        LoginContext lc = new LoginContext("KrbLogin", null, null, new CustomConfigurationByPassword());

        // 进行 Kerberos 认证
        lc.login();
        // 获取 Subject
        Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
        // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
        // 登出
        lc.logout();
    } catch (LoginException e) {
        // 处理登录异常
        e.printStackTrace();
    }
}

错误原因:说明没有MyCallbackHandler实现类,原先的传null
LoginContext lc = new LoginContext(“KrbLogin”, null, null, new CustomConfigurationByPassword());

解决方案:创建MyCallbackHandler实现类

MyCallbackHandler

package com.example.ldaptest2.entity;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

/**
 * @Author 211145187
 * @Date 2024/6/13 19:18
 **/
public class MyCallbackHandler implements CallbackHandler {
    @Override
    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof NameCallback) {
                // 处理用户名回调
                NameCallback nc = (NameCallback) callback;
                nc.setName("ldapadmin@NODE3.COM"); // 设置用户名
            } else if (callback instanceof PasswordCallback) {
                // 处理密码回调
                PasswordCallback pc = (PasswordCallback) callback;
                pc.setPassword("123456".toCharArray()); // 设置密码
            } else {
                throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
                // 其他类型的回调
                // 可以根据需要处理其他类型的回调
            }
        }
    }
}

测试类改为

LoginContext lc = new LoginContext("KrbLogin", null, null, new CustomConfigurationByPassword());

错误场景4:javax.security.auth.login.LoginException: Checksum failed

完整错误

Debug is  true storeKey true useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is ldapadmin@NODE3.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
                [Krb5LoginModule] user entered username: ldapadmin@NODE3.COM

                [Krb5LoginModule] authentication failed 
Checksum failed
javax.security.auth.login.LoginException: Checksum failed
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:808)
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:618)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
        at com.example.ldaptest2.controller.TestController.authenticateUserByPassword(TestController.java:66)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
Caused by: KrbException: Checksum failed
        at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:102)
        at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:94)
        at sun.security.krb5.EncryptedData.decrypt(EncryptedData.java:175)
        at sun.security.krb5.KrbAsRep.decrypt(KrbAsRep.java:150)
        at sun.security.krb5.KrbAsRep.decryptUsingPassword(KrbAsRep.java:139)
        at sun.security.krb5.KrbAsReqBuilder.resolve(KrbAsReqBuilder.java:310)
        at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:447)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:770)
        ... 100 more
Caused by: java.security.GeneralSecurityException: Checksum failed
        at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(AesDkCrypto.java:451)
        at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(AesDkCrypto.java:272)
        at sun.security.krb5.internal.crypto.Aes256.decrypt(Aes256.java:76)
        at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:100)
        ... 107 more
2024-06-18 11:10:14.040 ERROR 12994 --- [nio-8020-exec-1] c.e.ldaptest2.controller.TestController  : LoginException e:Checksum failed

错误原因:“Checksum failed” 错误通常表示 Kerberos 认证过程中出现了数据完整性校验失败的情况。这可能是由于传输过程中数据被篡改或损坏导致的。
在这里插入图片描述

错误代码,应该是nc.setName设置错值了,必须输入用户主体或者服务主体才能进行认证

public class MyCallbackHandler implements CallbackHandler {
    @Override
    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof NameCallback) {
                // 处理用户名回调
                NameCallback nc = (NameCallback) callback;
                nc.setName("ldapadmin"); // 设置用户名
            } else if (callback instanceof PasswordCallback) {
                // 处理密码回调
                PasswordCallback pc = (PasswordCallback) callback;
                pc.setPassword("123456".toCharArray()); // 设置密码
            } else {
                throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
                // 其他类型的回调
                // 可以根据需要处理其他类型的回调
            }
        }
    }
}

解决方案:修改nc.setName设置正确的值

解决方案:正确代码

public class MyCallbackHandler implements CallbackHandler {
    @Override
    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof NameCallback) {
                // 处理用户名回调
                NameCallback nc = (NameCallback) callback;
                nc.setName("ldapadmin@NODE3.COM"); // 设置用户名
            } else if (callback instanceof PasswordCallback) {
                // 处理密码回调
                PasswordCallback pc = (PasswordCallback) callback;
                pc.setPassword("123456".toCharArray()); // 设置密码
            } else {
                throw new UnsupportedCallbackException(callback, "Unrecognized Callback");
                // 其他类型的回调
                // 可以根据需要处理其他类型的回调
            }
        }
    }
}

错误场景5:javax.security.auth.login.LoginException: Message stream modified (41)

完整错误

Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is /etc/openldap/ldap.keytab refreshKrb5Config is false principal is ldap/bridge1@NODE3.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
                [Krb5LoginModule] authentication failed 
Message stream modified (41)
javax.security.auth.login.LoginException: Message stream modified (41)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:808)
        at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:618)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
        at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
        at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
        at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
        at com.example.ldaptest2.controller.TestController.authenticateUser(TestController.java:43)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
Caused by: KrbException: Message stream modified (41)
        at sun.security.krb5.KrbKdcRep.check(KrbKdcRep.java:101)
        at sun.security.krb5.KrbAsRep.decrypt(KrbAsRep.java:159)
        at sun.security.krb5.KrbAsRep.decryptUsingKeyTab(KrbAsRep.java:121)
        at sun.security.krb5.KrbAsReqBuilder.resolve(KrbAsReqBuilder.java:308)
        at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:447)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:780)
        ... 100 more

猜测原因1:有没有可能是krb5.confkrb5配置文件不对
解决方案:vim /etc/ krb5.conf
删除 krb5.conf 配置文件里的 renew_lifetime = xxx 这行配置即可(这点不确认,我的不是它造成的,但是网上有说这种也是一种办法)

猜测原因2:这个问题发生在kerberos和ldap都安装成功了,但是它两之间没互通,大白话:ldap和kerberos都安装了,但是它两谁都不认识谁,你认证个啥,他哪能认识。

解决方案:得让ldap认识kerberos,同时也得让kerberos认识ldap,具体实现思路就是https://www.cnblogs.com/swordfall/p/14682565.html#auto_id_7按照步骤2 、步骤3全部安装一遍,最后让kerberos使用ldap的数据库相当于共用数据库,这样当你页面输入ldap账户,后台拼接成用户主体就可以去kerberos中进行认证了

错误场景6:javax.security.auth.login.LoginException: null (68)

完整错误

		[Krb5LoginModule] authentication failed 
null (68)
	[LoginContext]: login REQUIRED failure
	[LoginContext]: abort ignored
javax.security.auth.login.LoginException: null (68)
	at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:804)
	at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
	at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
	at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
	at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
	at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
	at com.example.ldaptest2.KerberosTest.authenticateUser2(KerberosTest.java:58)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: KrbException: null (68)
	at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:76)
	at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:316)
	at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:361)
	at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:776)
	... 42 more
Caused by: KrbException: Identifier doesn't match expected value (906)
	at sun.security.krb5.internal.KDCRep.init(KDCRep.java:140)
	at sun.security.krb5.internal.ASRep.init(ASRep.java:64)
	at sun.security.krb5.internal.ASRep.<init>(ASRep.java:59)
	at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:60)
	... 45 more
2024-06-14 16:44:15.708  INFO 18160 --- [       Thread-1] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@18025ced: startup date [Fri Jun 14 16:44:04 CST 2024]; root of context hierarchy
Disconnected from the target VM, address: '127.0.0.1:12344', transport: 'socket'
LSA: Found Ticket
LSA: Made NewWeakGlobalRef
LSA: Found PrincipalName
LSA: Made NewWeakGlobalRef
LSA: Found DerValue
LSA: Made NewWeakGlobalRef
LSA: Found EncryptionKey
LSA: Made NewWeakGlobalRef
LSA: Found TicketFlags
LSA: Made NewWeakGlobalRef
LSA: Found KerberosTime
LSA: Made NewWeakGlobalRef
LSA: Found String
LSA: Made NewWeakGlobalRef
LSA: Found DerValue constructor
LSA: Found Ticket constructor
LSA: Found PrincipalName constructor
LSA: Found EncryptionKey constructor
LSA: Found TicketFlags constructor
LSA: Found KerberosTime constructor
LSA: Finished OnLoad processing

Process finished with exit code 0

在这里插入图片描述

错误原因1:keytab过期了

举例验证

[root@localhost ~]# ls -l /etc/openldap/ldap.keytab
-rwxrwxrwx 1 ldap ldap 1058 614 02:22 /etc/openldap/ldap.keytab
[root@localhost ~]#  等待输入超时:自动登出

解决方案:重新生成keytab就行

错误原因2:本地和服务器时间不一致
解决方案:同步时间

错误场景7:javax.security.auth.login.LoginException: Unable to obtain password from user

完整错误

Debug is  true storeKey true useTicketCache true useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is /etc/openldap/ldap.keytab refreshKrb5Config is true principal is ldapadmin@NODE3.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
Refreshing Kerberos configuration
Acquire TGT from Cache
Principal is ldapadmin@NODE3.COM
null credentials from Ticket Cache
Key for the principal ldapadmin@NODE3.COM not available in /etc/openldap/ldap.keytab
		[Krb5LoginModule] authentication failed 
Unable to obtain password from user


javax.security.auth.login.LoginException: Unable to obtain password from user


	at com.sun.security.auth.module.Krb5LoginModule.promptForPass(Krb5LoginModule.java:897)
	at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:760)
	at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
	at com.example.ldaptest2.KerberosTest.loginImpl(KerberosTest.java:100)
	at com.example.ldaptest2.KerberosTest.authenticateUser3(KerberosTest.java:76)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)

错误原因1:加载keytab认证报错,有没有可能是keytab指向不对,比如我window环境java客户端连接远程38.162服务器kerberos进行认证,那我肯定读不到服务器文件呀,我需要把文件下载到本地进行加载

错误代码:测试类

//keytab认证
@Test
public void authenticateUserByKeytab() {
    try {
        System.setProperty("java.security.krb5.conf", "C:\\Users\\211145187\\Desktop\\fsdownload\\krb5.conf");
        // 创建 LoginContext 对象,并为其提供自定义 Configuration
        LoginContext lc = new LoginContext("KrbLogin", null, null, new CustomConfigurationByKeytab());

        // 进行 Kerberos 认证
        lc.login();
        // 获取 Subject
        Subject subject = lc.getSubject();
//            logger.info("subject:{}", subject);
        // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
        // 登出
        lc.logout();
    } catch (LoginException e) {
        // 处理登录异常
        e.printStackTrace();
    }
}

配置类

package com.example.ldaptest2.config;

import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author 211145187
 * @Date 2024/6/13 16:34
 **/
// 自定义 Configuration 类,用于提供 Kerberos 登录配置
public class CustomConfigurationByKeytab extends Configuration {
    @Override
    public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
        if ("KrbLogin".equals(name)) {
            Map<String, String> options = new HashMap<>();
            options.put("useKeyTab", "true");   //指定是否使用 keytab 文件进行登录,这里设置为 true,表示使用 keytab 文件。
            options.put("keyTab", "/etc/openldap/ldap.keytab"); //指定 keytab 文件的路径,这里设置为 "/etc/openldap/ldap.keytab"。
            options.put("storeKey", "true");    //指定是否将密钥存储在 Subject 中,这里设置为 true,表示存储密钥。
            options.put("useTicketCache", "false"); //指定是否使用票据缓存,这里设置为 false,表示不使用票据缓存。
            options.put("doNotPrompt", "true"); //指定是否禁止提示用户输入用户名和密码,这里设置为 true,表示禁止提示。
            options.put("debug", "true");   //指定是否启用调试模式,这里设置为 true,表示启用调试模式。
            options.put("principal", "ldapadmin@NODE3.COM"); //指定要使用的主体名称,这里设置为 "ldap/bridge1@NODE3.COM",表示使用的服务主体。

            // 定义 Kerberos 登录模块的配置项
            AppConfigurationEntry entry = new AppConfigurationEntry(
                    "com.sun.security.auth.module.Krb5LoginModule",
                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
                    options
            );
            return new AppConfigurationEntry[]{entry};
        }
        return null;
    }
}

解决方案:正确代码
options.put(“keyTab”, “C:\Users\211145187\Desktop\fsdownload\ldap.keytab”);

错误原因2:如果你的项目部署在linux服务器上运行,进行接口联调报错,也有可能是你的keytab文件权限不够

解决方案:执行下面命令赋权

# chmod 777 ***.keytab

五、认证成功的结果打印

通过输入用户+keytab方式认证成功打印

测试方法

//keytab认证
@Test
 public void authenticateUserByKeytab() {
     try {
         System.setProperty("java.security.krb5.conf", "C:\\Users\\211145187\\Desktop\\fsdownload\\krb5.conf");
         // 创建 LoginContext 对象,并为其提供自定义 Configuration
         LoginContext lc = new LoginContext("KrbLogin", null, null, new CustomConfigurationByKeytab());

         // 进行 Kerberos 认证
         lc.login();
         // 获取 Subject
         Subject subject = lc.getSubject();
            logger.info("subject:{}", subject);
         // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
         // 登出
         lc.logout();
     } catch (LoginException e) {
         // 处理登录异常
         e.printStackTrace();
     }
 }

结果打印

Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is C:\Users\211145187\Desktop\fsdownload\ldap.keytab refreshKrb5Config is false principal is ldapadmin@NODE3.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
principal is ldapadmin@NODE3.COM
Will use keytab
Commit Succeeded 

2024-06-20 21:26:09.685  INFO 2972 --- [           main] com.example.ldaptest2.KerberosTest       : subject:主体: 
	主用户: ldapadmin@NODE3.COM
	专用身份证明: Ticket (hex) = 
0000: 61 82 01 3A 30 82 01 36   A0 03 02 01 05 A1 0B 1B  a..:0..6........
0010: 09 4E 4F 44 45 33 2E 43   4F 4D A2 1E 30 1C A0 03  .NODE3.COM..0...
0020: 02 01 02 A1 15 30 13 1B   06 6B 72 62 74 67 74 1B  .....0...krbtgt.
0030: 09 4E 4F 44 45 33 2E 43   4F 4D A3 82 01 00 30 81  .NODE3.COM....0.
0040: FD A0 03 02 01 12 A1 03   02 01 01 A2 81 F0 04 81  ................
0050: ED 2E AF 51 90 61 B4 EB   E1 BD 2A F5 A5 23 E5 E8  ...Q.a....*..#..
0060: E1 61 8A 80 D7 56 73 79   8F CA 63 7D 70 05 96 73  .a...Vsy..c.p..s
0070: 57 A2 FA B7 59 F7 82 85   89 67 3C 4E F0 85 4C D3  W...Y....g<N..L.
0080: 18 E3 9F B7 D5 91 35 FB   3B E4 F6 63 69 CB 59 06  ......5.;..ci.Y.
0090: CC 61 DC 08 78 BD 48 5D   B9 55 8A 32 E6 DE 0B 74  .a..x.H].U.2...t
00A0: 04 BF DF BE 71 FA 82 C7   B8 1B FE BF F6 69 84 32  ....q........i.2
00B0: 63 17 56 86 F7 19 2E 81   82 62 2B CD 25 3E 47 2B  c.V......b+.%>G+
00C0: 54 7F C1 55 9F CA F8 22   44 A5 A1 01 65 0D 48 7E  T..U..."D...e.H.
00D0: 9A 54 F8 C6 96 7F 1B 9B   AF A2 E5 BA EB C3 AA 59  .T.............Y
00E0: 78 A0 AD 42 BB ED 00 3C   B0 86 0C C6 35 0B E4 41  x..B...<....5..A
00F0: AB 78 DF 08 D7 01 06 6F   8F 0B 17 86 E5 0D D9 9C  .x.....o........
0100: D8 36 D3 7F 97 46 D2 FA   71 1D 60 82 8D EA FD 8F  .6...F..q.`.....
0110: 6D 06 92 D5 70 B1 8E CE   C0 BC 49 E6 3C F4 06 15  m...p.....I.<...
0120: 1C 6A F3 B7 99 95 4C 8A   76 81 F8 2F D3 88 43 4F  .j....L.v../..CO
0130: A3 BB C4 91 03 7A 90 56   71 94 67 0C 30 9B        .....z.Vq.g.0.

Client Principal = ldapadmin@NODE3.COM
Server Principal = krbtgt/NODE3.COM@NODE3.COM
Session Key = EncryptionKey: keyType=18 keyBytes (hex dump)=
0000: F5 B3 A5 15 58 AB E4 57   5A F7 D8 BF 55 6A 48 01  ....X..WZ...UjH.
0010: 90 1F 18 98 1C 01 3C 41   B6 73 04 FA 81 4A 83 74  ......<A.s...J.t


Forwardable Ticket true
Forwarded Ticket false
Proxiable Ticket false
Proxy Ticket false
Postdated Ticket false
Renewable Ticket false
Initial Ticket false
Auth Time = Thu Jun 20 13:25:51 CST 2024
Start Time = Thu Jun 20 13:25:51 CST 2024
End Time = Fri Jun 21 13:25:51 CST 2024
Renew Till = null
Client Addresses  Null 
	专用身份证明: C:\Users\211145187\Desktop\fsdownload\ldap.keytab for ldapadmin@NODE3.COM

		[Krb5LoginModule]: Entering logout
		[Krb5LoginModule]: logged out Subject

通过输入用户+密码方式认证成功打印

测试方法

//用户+密码认证
@Test
public void authenticateUserByPassword() {
    try {
        System.setProperty("java.security.krb5.conf", "C:\\Users\\211145187\\Desktop\\fsdownload\\krb5.conf");
        // 创建 LoginContext 对象,并为其提供自定义 Configuration
        LoginContext lc = new LoginContext("KrbLogin", null, new MyCallbackHandler(), new CustomConfigurationByPassword());

        // 进行 Kerberos 认证
        lc.login();
        // 获取 Subject
        Subject subject = lc.getSubject();
        logger.info("subject:{}", subject);
        // 在这里可以使用 subject 来执行进一步的操作,如访问受限资源
        // 登出
        lc.logout();
    } catch (LoginException e) {
        // 处理登录异常
        e.printStackTrace();
    }
}

结果打印

Debug is  true storeKey true useTicketCache false useKeyTab false doNotPrompt false ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is false principal is testldap3@NODE3.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
		[Krb5LoginModule] user entered username: testldap3@NODE3.COM

principal is testldap3@NODE3.COM
EncryptionKey: keyType=18 keyBytes (hex dump)=0000: DB 82 B1 63 50 1F E2 7B   8F DD F3 CD 45 04 5C D5  ...cP.......E.\.
0010: 68 B0 8A 41 76 38 44 AD   74 C9 49 77 76 AC 4E 55  h..Av8D.t.Iwv.NU

EncryptionKey: keyType=17 keyBytes (hex dump)=0000: BD FE 08 A2 B3 B9 59 55   8B 3F 24 B4 4F 04 20 09  ......YU.?$.O. .

EncryptionKey: keyType=16 keyBytes (hex dump)=0000: 9B 75 D6 BC F7 57 6D E3   7C C7 7C 13 61 A7 C7 BF  .u...Wm.....a...
0010: C2 AE 31 20 64 92 D3 9E                            ..1 d...

EncryptionKey: keyType=23 keyBytes (hex dump)=0000: 32 ED 87 BD B5 FD C5 E9   CB A8 85 47 37 68 18 D4  2..........G7h..

Added server's keyKerberos Principal testldap3@NODE3.COMKey Version 0key EncryptionKey: keyType=18 keyBytes (hex dump)=
0000: DB 82 B1 63 50 1F E2 7B   8F DD F3 CD 45 04 5C D5  ...cP.......E.\.
0010: 68 B0 8A 41 76 38 44 AD   74 C9 49 77 76 AC 4E 55  h..Av8D.t.Iwv.NU


		[Krb5LoginModule] added Krb5Principal  testldap3@NODE3.COM to Subject
Added server's keyKerberos Principal testldap3@NODE3.COMKey Version 0key EncryptionKey: keyType=17 keyBytes (hex dump)=
0000: BD FE 08 A2 B3 B9 59 55   8B 3F 24 B4 4F 04 20 09  ......YU.?$.O. .


		[Krb5LoginModule] added Krb5Principal  testldap3@NODE3.COM to Subject
Added server's keyKerberos Principal testldap3@NODE3.COMKey Version 0key EncryptionKey: keyType=16 keyBytes (hex dump)=
0000: 9B 75 D6 BC F7 57 6D E3   7C C7 7C 13 61 A7 C7 BF  .u...Wm.....a...
0010: C2 AE 31 20 64 92 D3 9E                            ..1 d...


		[Krb5LoginModule] added Krb5Principal  testldap3@NODE3.COM to Subject
Added server's keyKerberos Principal testldap3@NODE3.COMKey Version 0key EncryptionKey: keyType=23 keyBytes (hex dump)=
0000: 32 ED 87 BD B5 FD C5 E9   CB A8 85 47 37 68 18 D4  2..........G7h..


		[Krb5LoginModule] added Krb5Principal  testldap3@NODE3.COM to Subject
Commit Succeeded 

2024-06-20 21:27:33.264  INFO 14228 --- [           main] com.example.ldaptest2.KerberosTest       : subject:主体: 
	主用户: testldap3@NODE3.COM
	专用身份证明: Ticket (hex) = 
0000: 61 82 01 3A 30 82 01 36   A0 03 02 01 05 A1 0B 1B  a..:0..6........
0010: 09 4E 4F 44 45 33 2E 43   4F 4D A2 1E 30 1C A0 03  .NODE3.COM..0...
0020: 02 01 02 A1 15 30 13 1B   06 6B 72 62 74 67 74 1B  .....0...krbtgt.
0030: 09 4E 4F 44 45 33 2E 43   4F 4D A3 82 01 00 30 81  .NODE3.COM....0.
0040: FD A0 03 02 01 12 A1 03   02 01 01 A2 81 F0 04 81  ................
0050: ED FE 25 0E 39 64 4F 1C   1E B6 AB 80 B6 EA 8C 6C  ..%.9dO........l
0060: 6E 6A 87 FC 46 96 05 71   8C 79 39 63 BB 60 38 08  nj..F..q.y9c.`8.
0070: D6 88 88 88 43 DE 52 E4   BB 26 5E 79 6E 97 2F 53  ....C.R..&^yn./S
0080: 8E CA FB 46 A5 EC B9 A6   E6 98 53 A6 AE 8A 2A B3  ...F......S...*.
0090: A6 04 49 6B 38 50 A0 35   D6 F1 19 4D 29 68 E1 F8  ..Ik8P.5...M)h..
00A0: FF F8 47 88 B3 B3 60 D1   E5 B7 1F 4F 51 09 AF 69  ..G...`....OQ..i
00B0: AA A4 35 81 80 C2 A4 26   BE 18 AF 94 11 DC 13 43  ..5....&.......C
00C0: B2 67 D2 D9 BC B4 86 41   D3 7E D8 38 7A C4 72 FB  .g.....A...8z.r.
00D0: 0C DD B8 29 B2 71 97 21   55 63 07 65 AC EB 8D 42  ...).q.!Uc.e...B
00E0: 7D 61 4E EF 43 6C 5F C7   0C 49 55 4A 75 8E B1 DB  .aN.Cl_..IUJu...
00F0: 1A 7B BB 6B 1D 09 C3 1A   99 DB 48 E8 76 6A 74 7B  ...k......H.vjt.
0100: 02 41 36 46 A9 85 ED 83   6B 38 C7 83 69 01 AD 21  .A6F....k8..i..!
0110: A3 3A C7 2E C7 FC 7B 95   5D C2 37 32 7A CE E2 78  .:......].72z..x
0120: D9 0B 92 EA 09 0F C4 0E   05 16 D0 34 4A 2F 13 30  ...........4J/.0
0130: 5F 64 0B 6B D6 21 5C 2D   CE 62 74 D3 E9 18        _d.k.!\-.bt...

Client Principal = testldap3@NODE3.COM
Server Principal = krbtgt/NODE3.COM@NODE3.COM
Session Key = EncryptionKey: keyType=18 keyBytes (hex dump)=
0000: 64 10 86 D7 60 E4 2A 44   87 84 32 3E 56 C5 FA 80  d...`.*D..2>V...
0010: DC 7B 47 FF AA 2F A5 CB   C4 B6 D0 FD 31 9C 46 BC  ..G../......1.F.


Forwardable Ticket true
Forwarded Ticket false
Proxiable Ticket false
Proxy Ticket false
Postdated Ticket false
Renewable Ticket false
Initial Ticket false
Auth Time = Thu Jun 20 13:27:14 CST 2024
Start Time = Thu Jun 20 13:27:14 CST 2024
End Time = Fri Jun 21 13:27:14 CST 2024
Renew Till = null
Client Addresses  Null 
	专用身份证明: Kerberos Principal testldap3@NODE3.COMKey Version 0key EncryptionKey: keyType=18 keyBytes (hex dump)=
0000: DB 82 B1 63 50 1F E2 7B   8F DD F3 CD 45 04 5C D5  ...cP.......E.\.
0010: 68 B0 8A 41 76 38 44 AD   74 C9 49 77 76 AC 4E 55  h..Av8D.t.Iwv.NU


	专用身份证明: Kerberos Principal testldap3@NODE3.COMKey Version 0key EncryptionKey: keyType=17 keyBytes (hex dump)=
0000: BD FE 08 A2 B3 B9 59 55   8B 3F 24 B4 4F 04 20 09  ......YU.?$.O. .


	专用身份证明: Kerberos Principal testldap3@NODE3.COMKey Version 0key EncryptionKey: keyType=16 keyBytes (hex dump)=
0000: 9B 75 D6 BC F7 57 6D E3   7C C7 7C 13 61 A7 C7 BF  .u...Wm.....a...
0010: C2 AE 31 20 64 92 D3 9E                            ..1 d...


	专用身份证明: Kerberos Principal testldap3@NODE3.COMKey Version 0key EncryptionKey: keyType=23 keyBytes (hex dump)=
0000: 32 ED 87 BD B5 FD C5 E9   CB A8 85 47 37 68 18 D4  2..........G7h..



		[Krb5LoginModule]: Entering logout
		[Krb5LoginModule]: logged out Subject

六、其他报错可参考文档

Kerberos相关问题进行故障排除| 常见错误和解决方法

本人其他相关文章链接

1.Centos7.9安装openldap
2.Centos7.9安装kerberos
3.Openldap集成Kerberos
4.Centos7.9安装phpldapadmin
5.java连接ldap实现用户查询功能
6.java连接kerberos用户认证
7.javax.security.auth.login.LoginException: Unable to obtain password from user
8.javax.security.auth.login.LoginException: null (68)
9.javax.security.auth.login.LoginException: Message stream modified (41)
10.javax.security.auth.login.LoginException: Checksum failed
11.javax.security.auth.login.LoginException: No CallbackHandler available to garner authentication info
12.javax.security.auth.login.LoginException: Cannot locate KDC
13.javax.security.auth.login.LoginException: Receive timed out
14.java: 无法访问org.springframework.context.ConfigurableApplicationContext
15.LDAP: error code 34 - invalid DN
16.LDAP: error code 32 - No Such Object
17.java: 无法访问org.springframework.ldap.core.LdapTemplate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1845197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI播客下载:Possible(OpenAI投资人Reid Hoffman主持)

这是由 LinkedIn 创办人&#xff0c;同时也是 OpenAI 早期投资者 Reid Hoffman。节目上会邀请各领域的专家 (教育、医疗、司法)&#xff0c;探讨 AI 对世界的影响。这节目特别有趣的地方&#xff0c;是在 GPT-4 协助下制作的&#xff0c;开创了人机协作内容 。 如果未来一切都能…

Windows10任务栏卡顿解决方案

一、重新启动任务资源管理器 右键底部任务栏选择“任务管理器”&#xff1b;按快捷键“CtrlShiftEsc”&#xff1b;搜索框搜索“任务管理器”并单击“打开”&#xff1b;“WinX”打开开始菜单附属菜单&#xff0c;在列表中选择“任务管理器” &#xff1b;按下“ctrlaltdelete”…

Linux管道与重定向

管道 是进程通信的方法之一&#xff0c;在Linux中用命令1|命令2的形式表示&#xff0c;将前一个命令的结果作为后续命令的参数进行输入&#xff0c;也有tee管道&#xff0c;可以进行多次筛选&#xff0c;即多次使用|过滤命令。 重定向 文件描述符FD Linux中输入输出分为三种…

HTTP 抓包工具——Fiddler项目实战

网络爬虫实质上是模拟浏览器向 Web 服务器发送请求。对于一些简单的网络请求&#xff0c;我们 可以通过查看 URL 地址来构造请求&#xff0c;但对于一些稍复杂的网络请求&#xff0c;仍然通过观察 URL 地 址将无法构造正确。因此我们需要对这些复杂的网络请求进行捕获分…

高考填报志愿,性格决定命运

所谓性格决定命运&#xff0c;也即是强调了性格在左右我们的人生&#xff0c;性格会和个人的未来成就相挂钩&#xff0c;当一个人向来小心谨慎时&#xff0c;适合一些与数字打交道的工作&#xff0c;也可以从事一些比较细致点的工作&#xff0c;如果一个人向来大大咧咧&#xf…

【Linux命令入门】shell命令解析与PATH环境变量

文章目录 前言1.Linux shell 简介2. Linux命令提示符Linux命令的组成环境变量设置环境变量永久设置临时设置总结前言 Linux命令行(shell)是与操作系统交互的重要工具。通过学习和掌握基本的shell命令,用户可以高效地管理文件、执行程序和处理系统任务。PATH环境变量在Linux…

SpringBoot【3】集成 Swagger

SpringBoot 集成 Swagger 前言pom.xml 配置文件application.yml 配置文件config 包Swagger2Config entity 包UserEntity service 包impl 包SwaggerServiceImpl SwaggerService controller 包SwaggerController SwaggerApplication验证 前言 创建项目步骤、及版本选择等&#x…

从0开始C++(五):友元函数运算符重载

友元函数 介绍 C中的友元函数是一种特殊的函数&#xff0c;它可以访问和操作类的私有成员和保护成员。友元函数可以在类的内部或外部声明和定义&#xff0c;但在其声明和定义中需要使用关键字 friend 来标识。友元函数可以是全局函数&#xff0c;也可以是其他类的成员函数。 …

智慧农业解决方案:华测农机导航技术助力无人农场高效作业

在金黄的麦田、翠绿的稻田中&#xff0c;农机导航正成为无人农场的新星。如今&#xff0c;无人收割、无人播种、无人插秧等作业模式已不再是遥不可及的梦想&#xff0c;而是智慧农业快速发展中的现实写照。搭载华测导航技术的农机&#xff0c;正在田间地头忙碌。它们如同舞者般…

71-TCP协议工作原理及实战

一 服务器端 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QTcpServer> // 专门用于建立TCP连接并传输数据信息 #include <QtNetwork> // 此模块提供开发TCP/IP客户端和服务器的类QT_BEGIN_NAMESPACE namespace Ui { class M…

亲测5个电脑浏览器高效技巧,保证让你搜索效率倍增!

虽然我们每个人的电脑基本每天都会用到浏览器&#xff0c;但你会发现有的人用起浏览器就是噼里啪啦的&#xff0c;找他要个什么网站他都能快速找到&#xff0c;而有的人&#xff0c;经常打开的是广告搜索的网页&#xff0c;找不到搜索的答案非常慢。小编今天就来跟你分享一下我…

跨区域文件管控解决方案,一文了解

跨区域文件管控是一个涉及在不同地域或区域之间管理和控制文件的过程&#xff0c;它包括安全性、合规性和管理效率等多个方面。以下是一些关键的考量因素&#xff1a; 1.安全性&#xff1a;确保在传输过程中文件不被截获、篡改或泄露。使用加密技术保护文件&#xff0c;并确保传…

解释React中的“端口(Portals)”是什么,以及如何使用它来渲染子节点到DOM树以外的部分。

React中的“端口&#xff08;Portals&#xff09;”是一种将子节点渲染到DOM****树以外的部分的技术。在React应用中&#xff0c;通常情况下组件的渲染是遵循DOM的层次结构&#xff0c;即子组件会渲染在父组件的DOM节点内部。然而&#xff0c;有些情况下&#xff0c;开发者可能…

ArcGIS图斑分区(组)排序—从上到下从左到右

​​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 ArcGIS图斑分区&#xff08;组&#xff09;从上到下从左到右排序 是之前的内容的升级 GIS技巧100例——12ArcGIS图斑空间排序 关于今天的内容 我们在19年已经和大家分…

Linux机器通过Docker-Compose安装Jenkins发送Allure报告

目录 一、安装Docker 二、安装Docker Compose 三、准备测试用例 四、配置docker-compose.yml 五、启动Jenkins 六、配置Jenkins和Allure插件 七、创建含pytest的Jenkins任务 八、项目结果通知 1.通过企业微信通知 2.通过邮件通知 最近小编接到一个任务用来监测和巡检网…

win10手动安装stable-diffusion-webui

目录 1.python下载安装 2.git下载安装 3.stable-diffusion-webui下载 4.安装s-d-webui的依赖包&#xff08;用国内镜像提速&#xff09; 5.git下载的stable-diffusion-webui&#xff0c;依赖包提示已安装&#xff0c;但运行webui-user.bat后&#xff0c;又开始下载 6.修…

YOLOv10改进 | Neck | 添加双向特征金字塔BiFPN【含二次独家创新】

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录&#xff1a;《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有40篇内容&#xff0c;内含各种Head检测头、损失函数Loss、B…

教你使用Python玩转MySQL数据库,大数据导入不再是难题!

数据分析离不开数据库&#xff0c;如何使用python连接MySQL数据库&#xff0c;并进行增删改查操作呢&#xff1f; 我们还会遇到需要将大批量数据导入数据库的情况&#xff0c;又该如何使用Python进行大数据的高效导入呢&#xff1f; 本文会一一讲解&#xff0c;并配合代码和实…

疯狂刷题python版 | 使用PySide6自制刷题软件【源码+解析】

疯狂刷题python版 | 使用PySide6自制刷题软件【源码解析】 一、前言二、思考三、软件设计四、软件实现&#xff08;一&#xff09;使用QWebEngineView控件通过JavaScript代码和chrome内核进行数据交互和逻辑控制&#xff08;二&#xff09;用户分别通过浏览器 GUI和PySide6 GUI…

秋招突击——6/19——复习{(单调队列优化)——最大子序列和,背包问题——宠物小精灵收服问题}——新作{两两交换链表中的节点}

文章目录 引言复习单调队列优化——最大子序列和思路分析实现代码参考实现 背包问题——宠物小精灵的收服问题个人实现参考实现 新作两两交换链表中的节点个人实现参考实现 删除有序数组中的重复项个人实现知识补全迭代器的访问和控制vector删除特定的元素erasevector底层删除元…