web-dev-qa-db-fra.com

Client Kerberos simple en Java?

Des applications telles que Google Chrome et IE peuvent gérer de manière transparente l'authentification Kerberos; cependant, je ne trouve pas de "simple" Java solution pour correspondre à cette transparence.Toutes les solutions que j'ai trouvées nécessitent la présence d'un fichier krb5.conf et d'un fichier login.conf que les applications ci-dessus semblent exiger.

Quelle est la meilleure façon de créer une application Java avec des capacités Kerberos SSO qui fonctionnent simplement?

[mise à jour]: pour être clair, j'ai besoin d'un CLIENT solution latérale pour création de tickets pas les valider. De plus, il semble que SPNEGO soit le protocole "wrapper" par défaut qui finira par être délégué à Kerberos, mais je dois également pouvoir gérer le protocole SPNEGO.

35
Andrew White

Oracle a n exemple utilisant SaslClient de Java . Je ne suis pas un programmeur Java, mais quand je l'ai signalé une fois à quelqu'un qui l'a fait, il a pu le faire fonctionner assez rapidement. Il peut encore nécessiter un fichier "conf" quelque part ( nb Kerberos utilise des variables d'environnement, commençant souvent par KRB5_, pour savoir où chercher de tels fichiers. Notez également que Kerberos lui-même n'inclut aucun transport d'aucune sorte - votre application doit savoir comment envoyer et recevoir les charges utiles Kerberos manière que le serveur attend (et cela est différent selon le serveur avec lequel vous essayez de vous authentifier).

Modifier: vous avez modifié votre question, voici donc un lien lié à SPNEGO dans Java qui pourrait être utile: http://download.Oracle.com/javase/6/ docs/technotes/guides/security/jgss/lab/part5.html

8
John Zwinck

Il existe maintenant une solution simple pour cela en utilisant Apache HTTP Components Client 4.5 ou supérieur. Ceci est toujours marqué comme expérimental en 4.5, donc votre kilométrage peut varier, mais cela fonctionne bien pour moi dans un contexte d'entreprise.

En plus des pots client HC 4.5, vous aurez besoin d'avoir les pots httpclient-win, jna et jna-platform sur votre chemin de classe, comme fourni avec http-component-client. Vous construisez ensuite un client HC compatible Kerberos comme suit:

CloseableHttpClient httpclient = WinHttpClients.createDefault();

Ou en utilisant le constructeur:

HttpClientBuilder clientBuilder = WinHttpClients.custom();

Qui peut ensuite être personnalisé selon les besoins avant de créer le client:

CloseableHttpClient client = clientBuilder.build();

Cette solution fonctionne sans aucune configuration externe et résout surtout le problème de rupture du mécanisme JRE intégré pour les utilisateurs disposant de droits d'administrateur local sur Windows 7+. Cela est possible car le ticket Kerberos est récupéré directement à partir de l'API SSPI via JNA, plutôt que de passer par le GSSAPI fourni par le JRE.

Exemple de code de l'équipe http-components

Tout cela a été rendu possible grâce au bon travail de Daniel DoubrovkineTimothy Wall et Ryan McKinley

13
Malcolm Smith

Ajout à la réponse de David Roussels sur l'authentification Kerberos basée sur http spécifique à l'URL: -

La raison pour laquelle votre code fonctionne est que votre SPN cible (principal côté serveur) est configuré avec HTTP/[email protected]. Dans ce cas, cela fonctionnera car vous ne définissez pas explicitement le jeton. URLConnection définit en interne un jeton avec ce SPN

1 Effectuez les étapes (de ma réponse précédente) pour obtenir un sujet

2 Utilisez gss api init sec context pour générer un jeton de contexte. Il existe de nombreux didacticiels pour cette étape

3 Base 64 encoder le jeton

4 Attachez le jeton à la connexion url: -

URL url = new URL("http://myhost/myapp")
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); = 
urlConn.setRequestProperty("Authorization", "Negotiate " + encodedToken);

5 Mettre en œuvre une action privilégiée: -

//this internally calls the getInputStream
public class PrivilegedGetInputStream implements PrivilegedExceptionAction<InputStream>

6 Enveloppez le tout dans Subject.doAs

//use prev answer instructions to get subject
Subject.doAs(subject, new PrivilegedGetInputStream(urlConnection)
9
Arunav Sanyal

Vous n'avez vraiment rien à faire. Dans Java 6, sur une machine cliente Windows, vous pouvez faire ceci:

new URL("http://myhost/myapp").openStream();

Et négocier l'authentification fonctionne. Au moins, c'est le cas pour moi. Et le serveur sur lequel j'ai testé ne prend en charge que Negotiate, pas l'authentification NTLM.

7
David Roussel

Ok si vous voulez éviter d'utiliser un fichier login.conf, vous devez coder différemment: -

//define your own configuration
import javax.security.auth.login.Configuration;
public class CustomLoginConfiguration extends Configuration

//pass certain parameters to its constructor
//define an config entry
import javax.security.auth.login.AppConfigurationEntry;
private AppConfigurationEntry configEntry;

//define a map of params you wish to pass and fill them up
//the map contains entries similar to one you have in login.conf
Map<String, String> params = new HashMap<String, String>();

//define the configuration
configEntry = new AppConfigurationEntry(
            "com.Sun.security.auth.module.Krb5LoginModule",
            AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, params);

//implement getappconfig method
public AppConfigurationEntry[] getAppConfigurationEntry() {
    return new AppConfigurationEntry[] { configEntry };
}

Maintenant, une fois que vous avez terminé avec cette définition, vous pouvez l'utiliser pour utiliser pour récupérer les tickets de kdc

//get ticket in login context
LoginContext lc = null;
    lc = new LoginContext("lc", null, callback, new CustomLoginConfiguration(argumentlist));
    lc.login();

À partir d'ici, vous pouvez récupérer le sujet jaas et pouvez essentiellement faire une tonne de choses d'authentification.

Au cas où vous auriez besoin d'autres pointeurs, laissez un commentaire.

4
Arunav Sanyal

Vous pouvez utiliser les propriétés système au lieu des fichiers de configuration pour spécifier le nom d'hôte KDC et le nom du service, mais ces choses (au moins) sont obligatoires ....

Waffle vous fournira en fait les informations dont vous avez besoin pour définir la plupart des propriétés, même si vous ne recevrez pas de ticket. Regardez la classe WindowsAuthProviderImpl (le fichier d'aide Waffle.chm montre l'API).

J'utilise JAAS pour obtenir un ticket de service auprès d'Active Directory en deux étapes:

  1. Utilisez Krb5LoginModule pour récupérer le TGT mis en cache et l'ajouter au sujet.

  2. Utilisez l'objet et l'API GSS pour récupérer un ticket de service à partir du KDC.

Il y a beaucoup de bonnes informations et d'exemples de code sur The Java Way of Active Directory .

2
Mermeister

J'ai créé un petit outil pour simplifier la connexion avec httpclient à kerberos, vous voudrez peut-être l'essayer. https://github.com/DovAmir/httpclientAuthHelper

DefaultHttpClient httpclient = new DefaultHttpClient();
AuthUtils.securityLogging(SecurityLogType.KERBEROS,true);
CredentialsUtils.setKerberosCredentials(client, new UsernamePasswordCredentials("xxx", "xxx"), "domain", "kdc");
client.executeMethod(httpget);
1
dov.amir

Utilisez GAUFRE

0
Alex

Voici un bon article de blog sur l'utilisation d'un client Java à utiliser avec Kerberos http://sachithdhanushka.blogspot.com/2014/02/kerberos-Java-client-configuration.html

0
Sachith Withana