Java如何借助Kerberos实现身份认证

2025-10-20 08:16:37

1、分别为客户端和服务端创建登录KDC的用户。

使用kadmin.local工具。

#kadmin.local

#kadmin.local: addprinc sample/qibaofu.com@QIBAOFU.COM

#kadmin.local: addprinc test1/qibaofu.com@QIBAOFU.COM

创建完成后,查看用户:

客户端为:test1,服务端为:sample

Java如何借助Kerberos实现身份认证

2、使用ping查看配置的主机名是否正常。此例子中,主机名为qibaofu.com,若是出现如下结果,则证明配置是正确的。

Java如何借助Kerberos实现身份认证

3、编写客户端程序。

import org.ietf.jgss.*;

import java.net.Socket;

import java.io.IOException;

import java.io.DataInputStream;

import java.io.DataOutputStream;

public class SampleClient {

    public static void main(String[] args) 

       throws IOException, GSSException  {

    System.setProperty("java.security.krb5.realm","QIBAOFU.COM");

    System.setProperty("java.security.krb5.kdc","qibaofu.com");

    System.setProperty("javax.security.auth.useSubjectCredsOnly","false");

    System.setProperty("java.security.auth.login.config","bcsLogin.conf");

    String server = "sample/qibaofu.com";

String hostName = "127.0.0.1";

int port = 8090;

Socket socket = new Socket(hostName, port);

DataInputStream inStream = 

 new DataInputStream(socket.getInputStream());

DataOutputStream outStream = 

 new DataOutputStream(socket.getOutputStream());

System.out.println("Connected to server " 

  + socket.getInetAddress());

Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");

GSSManager manager = GSSManager.getInstance();

GSSName serverName = manager.createName(server, null);

GSSContext context = manager.createContext(serverName,

krb5Oid,

null,

GSSContext.DEFAULT_LIFETIME);

context.requestMutualAuth(true);  // Mutual authentication

context.requestConf(true);  // Will use confidentiality later

context.requestInteg(true); // Will use integrity later

// Do the context eastablishment loop

byte[] token = new byte[0];

while (!context.isEstablished()) {

   // token is ignored on the first call

   token = context.initSecContext(token, 0, token.length);

   // Send a token to the server if one was generated by

   // initSecContext

   if (token != null) {

System.out.println("Will send token of size "

  + token.length

  + " from initSecContext.");

outStream.writeInt(token.length);

outStream.write(token);

outStream.flush();

   }

   // If the client is done with context establishment

   // then there will be no more tokens to read in this loop

   if (!context.isEstablished()) {

token = new byte[inStream.readInt()];

System.out.println("Will read input token of size "

  + token.length

  + " for processing by initSecContext");

inStream.readFully(token);

   }

}

System.out.println("Context Established! ");

System.out.println("Client is " + context.getSrcName());

System.out.println("Server is " + context.getTargName());

if (context.getMutualAuthState())

   System.out.println("Mutual authentication took place!");

byte[] messageBytes = "Hello There!\0".getBytes();

MessageProp prop =  new MessageProp(0, true);

token = context.wrap(messageBytes, 0, messageBytes.length, prop);

System.out.println("Will send wrap token of size " + token.length);

outStream.writeInt(token.length);

outStream.write(token);

outStream.flush();

token = new byte[inStream.readInt()];

System.out.println("Will read token of size " + token.length);

inStream.readFully(token);

context.verifyMIC(token, 0, token.length, 

 messageBytes, 0, messageBytes.length,

 prop);

System.out.println("Verified received MIC for message.");

System.out.println("Exiting...");

context.dispose();

socket.close();

    }

}

Java如何借助Kerberos实现身份认证

4、编写服务端程序。

import org.ietf.jgss.*;

import java.io.*;

import java.net.Socket;

import java.net.ServerSocket;

public class SampleServer  {

    

    public static void main(String[] args) 

throws IOException, GSSException {

   

    System.setProperty("java.security.krb5.realm","QIBAOFU.COM");

    System.setProperty("java.security.krb5.kdc","qibaofu.com");

    System.setProperty("javax.security.auth.useSubjectCredsOnly","false");

    System.setProperty("java.security.auth.login.config","bcsLogin.conf");

int localPort = 8090;

ServerSocket ss = new ServerSocket(localPort);

GSSManager manager = GSSManager.getInstance();

while (true) {

   System.out.println("Waiting for incoming connection...");

   Socket socket = ss.accept();

   DataInputStream inStream =

new DataInputStream(socket.getInputStream());

   DataOutputStream outStream = 

new DataOutputStream(socket.getOutputStream());

   System.out.println("Got connection from client "

      + socket.getInetAddress());

   GSSContext context = manager.createContext((GSSCredential)null);

   // Do the context eastablishment loop

   

   byte[] token = null;

   

   while (!context.isEstablished()) {

token = new byte[inStream.readInt()];

System.out.println("Will read input token of size "

  + token.length

  + " for processing by acceptSecContext");

inStream.readFully(token);

token = context.acceptSecContext(token, 0, token.length);

// Send a token to the peer if one was generated by

// acceptSecContext

if (token != null) {

   System.out.println("Will send token of size "

      + token.length

      + " from acceptSecContext.");

   outStream.writeInt(token.length);

   outStream.write(token);

   outStream.flush();

}

   }

   

   System.out.print("Context Established! ");

   System.out.println("Client is " + context.getSrcName());

   System.out.println("Server is " + context.getTargName());

    

   if (context.getMutualAuthState())

System.out.println("Mutual authentication took place!");

     

   MessageProp prop = new MessageProp(0, false);

   token = new byte[inStream.readInt()];

   System.out.println("Will read token of size " 

      + token.length);

   inStream.readFully(token);

   

   byte[] bytes = context.unwrap(token, 0, token.length, prop);

   String str = new String(bytes);

   System.out.println("Received data \"" 

      + str + "\" of length " + str.length());

   

   System.out.println("Confidentiality applied: "

      + prop.getPrivacy());

    

   prop.setQOP(0);

   

   token = context.getMIC(bytes, 0, bytes.length, prop);

   

   System.out.println("Will send MIC token of size " 

      + token.length);

   outStream.writeInt(token.length);

   outStream.write(token);

   outStream.flush();

   System.out.println("Closing connection with client " 

      + socket.getInetAddress());

   context.dispose();

   socket.close();

}

    }

}

Java如何借助Kerberos实现身份认证

5、启动服务端程序,然后接着启动客户端程序。

Java如何借助Kerberos实现身份认证

Java如何借助Kerberos实现身份认证

6、执行客户端程序后,会提示输入用户名和密码,客户端输入后,会接着提示服务端也输入,因为此程序为互相认证,所以服务端也需要输入用户名和密码。

Java如何借助Kerberos实现身份认证

Java如何借助Kerberos实现身份认证

7、服务端输入密码后,此时可以发现服务可以正常执行完毕。

Java如何借助Kerberos实现身份认证

Java如何借助Kerberos实现身份认证

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢