我正在做kerberos代表团。我注意到GSSUtil.createSubject(context.getSrcName(), clientCred)
返回的主题中没有凭据。
在此之前,我已经完成GSSCredential clientCred = context.getDelegCred();
并返回了凭据。
编辑:当我从同一域中的一台计算机访问我的服务时,它可以工作,而如果从同一域中的另一台计算机访问,则不能。
困惑AD需要哪些其他设置?
我们非常感谢您的帮助。
以下是我的代码:
public class KerberosTest {
public Subject loginImpl(byte[] kerberosTicket, String propertiesFileName) throws Exception {
System.setProperty("sun.security.krb5.debug", "true");
// // no effect // System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
final Krb5LoginModule krb5LoginModule = new Krb5LoginModule();
Subject serviceUserSubject = new Subject();
final Map<String,String> optionMap = new HashMap<String,String>();
HashMap<String, String> shared = new HashMap<>();
optionMap.put("keyTab", "C:\\kerberos_files\\sapuser.keytab");
optionMap.put("principal", "HTTP/SAPTEST@EQSECTEST.LOCAL"); // default realm
// optionMap.put("principal", "kerberosuser"); // default realm
optionMap.put("useFirstPass", "true");
optionMap.put("doNotPrompt", "true");
optionMap.put("refreshKrb5Config", "true");
optionMap.put("useTicketCache", "false");
optionMap.put("renewTGT", "false");
optionMap.put("useKeyTab", "true");
optionMap.put("storeKey", "true");
optionMap.put("isInitiator", "true");
optionMap.put("useSubjectCredsOnly", "false");
optionMap.put("debug", "true"); // switch on debug of the Java implementation
krb5LoginModule.initialize(serviceUserSubject, null, shared, optionMap);
// login using details mentioned inside keytab
boolean loginOk = krb5LoginModule.login();
System.out.println("Login success: " + loginOk);
// This API adds Kerberos Credentials to the the Subject's private credentials set
boolean commitOk = krb5LoginModule.commit();
}
System.out.println("Principal from subject: " + serviceUserSubject.getPrincipals()); // this must display name of user to which the keytab corresponds to
Subject clientSubject = getClientContext(serviceUserSubject, kerberosTicket);
System.out.println("Client Subject-> " + clientSubject);
System.out.println("Client principal-> "+clientSubject.getPrincipals().toArray()[0]);
return clientSubject;
}
// Completes the security context initialisation and returns the client name.
private Subject getClientContext(Subject subject, final byte[] kerberosTicket) throws PrivilegedActionException {
Subject clientSubject = Subject.doAs(subject, new KerberosValidateAction(kerberosTicket));
return clientSubject;
}
private class KerberosValidateAction implements PrivilegedExceptionAction<Subject> {
byte[] kerberosTicket;
public KerberosValidateAction(byte[] kerberosTicket) {
this.kerberosTicket = kerberosTicket;
}
@Override
public Subject run() throws Exception {
GSSManager gssManager = GSSManager.getInstance();
GSSContext context = gssManager.createContext((GSSCredential) null);
Oid kerberosOid = new Oid("1.2.840.113554.1.2.2");
// context.requestCredDeleg(true); // needed when we are demanding ticket from KDC. In our scenario, we are getting ticket from browser(client)
// Called by the context acceptor upon receiving a token from the peer. This is our context acceptor
// This method may return an output token which the application will need to send to the peer for further processing by its initSecContext call.
// We will only accept the incoming token from Peer (browser) and fwd it to third party system
while (!context.isEstablished()) {
byte[] nextToken = context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length);
}
boolean established = context.isEstablished();
String user = context.getSrcName().toString();
String serviceAccnt = context.getTargName().toString();
//check if the credentials can be delegated
if (!context.getCredDelegState()) {
System.out.println("credentials can not be delegated!");
return null;
}
//get the delegated credentials from the calling peer...
GSSCredential clientCred = context.getDelegCred();
//Create a Subject out of the delegated credentials.
//With this Subject the application server can impersonate the client that sent the request.
Subject clientSubject = GSSUtil.createSubject(context.getSrcName(), clientCred);
return clientSubject; // ***this contains only principal name and not credentials !!
}
}
答案 0 :(得分:0)
我发现了一个重要的观点,没有发现任何记载。 -
在AD中配置kerberos服务用户时,“信任此用户进行委派(仅Kerberos)”仅对保存此更改后创建的新TGT生效。
例如,如果用户在客户端计算机A上登录,例如在上午10:00。
管理员在上午10:30启用向kerberos服务用户的委派。
当用户从计算机A上的浏览器中访问应用程序URL时,该委派将不起作用,因为在启用委派之前(上午10:00)已创建了他的TGT。
如果用户从计算机A注销并重新登录,将生成新的TGT。委托现在非常适合该用户。