GSSContext、kerberos 身份验证、协商

问题描述 投票:0回答:1

我有简单的 java 端点来验证服务器 A 上的用户凭据 (这是我的java应用程序运行的地方)

因此,当用户点击 /kerberos-auth 时,它应该能够验证用户身份 连接到同一个 AD。用户应携带协商令牌

这是代码

public LoginResponse authenticateWithKerberos(String kerberosToken) throws GSSException {

        System.setProperty("java.security.krb5.conf", "C:/Windows/krb5.conf");
        System.setProperty("java.security.auth.login.config", "C:/Windows/jaas.conf");
        System.setProperty("sun.security.krb5.debug", "true");
        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
        System.setProperty("sun.security.krb5.disableReferrals", "true");

        kerberosToken = kerberosToken.replace('-', '+').replace('_', '/');
        int paddingLength = 4 - (kerberosToken.length() % 4);
        if (paddingLength < 4) {
            kerberosToken += "=".repeat(paddingLength);
        }

        byte[] tokenBytes = Base64.getDecoder().decode(kerberosToken);
        GSSManager gssManager = GSSManager.getInstance();
        Oid kerberosOid = new Oid(kerberosConfig.getOid());
        GSSName targetName = gssManager.createName(kerberosConfig.getServiceprincipal(), GSSName.NT_HOSTBASED_SERVICE);
        GSSContext gssContext = gssManager.createContext(targetName, kerberosOid, null, GSSContext.DEFAULT_LIFETIME);
        gssContext.requestMutualAuth(false);
        gssContext.requestCredDeleg(true);

        try {
            gssContext.initSecContext(tokenBytes, 0, tokenBytes.length);
            int atIndex = gssContext.getSrcName().toString().indexOf('@');
            String username = gssContext.getSrcName().toString().substring(0, atIndex);
            DetailUserResponse detailUserResponse = getUserWithSystemDetail(username);
            String token = jwtUtil.generateToken(detailUserResponse.getUser(), detailUserResponse.getSystemDetail());

            return new LoginResponse(token, detailUserResponse.getUser());
        }catch (Exception e){
            throw new UserNotFoundException(MessageConstants.USER_NOT_FOUND);
        }finally{
            gssContext.dispose();
        }
    }

服务器 A 使用 rikim 用户作为凭据/服务帐户。 然后用户 B 带着协商令牌与本地的票证缓存一起作为用户 ariandop

我的问题,当用户 B ariandop 提出请求时。 为什么我的应用程序一直被验证为 rikim ?而不是阿里安多普。

我的代码有问题吗? 请帮助我,谢谢...

我希望它验证为 ariandop,这是其本地的真实用户名凭据。 而是通过 rikim 进行身份验证,这是服务帐户。

我怎样才能实现它

java kerberos gssapi negotiate http-negotiate
1个回答
0
投票

服务器 A 使用 rikim 用户作为凭据/服务帐户。然后用户 B 以用户 ariandop 的身份在其本地使用带有票证缓存的协商令牌

避免使用常规用户帐户作为服务帐户 - 至少在生产中不要使用。服务(网络应用程序等)应该有一个专用帐户用于此目的。

我的问题,当用户 B ariandop 提出请求时。为什么我的应用程序一直被验证为 rikim ?而不是阿里安多普。

因为您实际上实现了 GSSAPI 的“客户端”(发起者)端,而不是“服务器”端。当您调用

initSecContext()
时,您是在告诉 GSSAPI 充当发起者。相反,服务器(接受方)需要使用从客户端接收到的令牌来调用
acceptSecContext()

© www.soinside.com 2019 - 2024. All rights reserved.