La lecture du nom d'utilisateur de ticket Kerberos dans l'en-tête d'Autorisation
Je veux lire le nom de l'utilisateur à partir du ticket Kerberos dans l'Autorisation d'en-tête HTTP. Je suis à l'aide de Java.
J'ai passé des jours à essayer de l'obtenir par la lecture à travers un tas de sites sur le sujet, mais n'ont pas été en mesure de le faire. Kerberos est nouveau/étranger à moi.
C'est ce que j'ai réalisé:
- Lorsqu'un utilisateur accède au site sans l'Autorisation d'en-tête, le serveur répond avec 401 + en-tête WWW-Authenticate=Négocier.
- Toutes sortes de choses magiques se produire du côté du client.
- Utilisateur revient avec une requête HTTP qui contient l'en-tête d'Autorisation avec une valeur comme: "Négocier YHcGB...=="
- Décoder le base64 billet à un tableau d'octets.
À partir de là, c'est un terrifiant voyage dans l'inconnu. Aussi loin que je peux dire, les prochaines étapes devraient être:
- De connexion à l'AD/Kerberos/Serveur avec un utilisateur.
- Décoder le billet.
C'est ce que j'ai:
de connexion.conf
ServicePrincipalLoginContext
{
com.sun.security.auth.module.Krb5LoginModule
required
principal="HTTP/[email protected]"
doNotPrompt=true
useTicketCache=true
password=mYpasSword
debug=true;
};
JavaClass.java
String encodedTicket = authorization.substring("Negotiate ".length());
byte[] ticket = Base64.decode(encodedTicket);
LoginContext lc = new LoginContext("ServicePrincipalLoginContext");
lc.login();
Subject serviceSubject = lc.getSubject();
Subject.doAs(serviceSubject, new ServiceTicketDecoder(ticket));
ServiceTicketDecoder.java
public String run() throws Exception {
Oid kerberos5Oid = new Oid("1.2.840.113554.1.2.2");
GSSManager gssManager = GSSManager.getInstance();
String service = "krbtgt/[email protected]";
GSSName serviceName = gssManager.createName(service, GSSName.NT_USER_NAME);
GSSCredential serviceCredentials = gssManager.createCredential(serviceName, GSSCredential.INDEFINITE_LIFETIME, kerberos5Oid, GSSCredential.ACCEPT_ONLY);
GSSContext gssContext = gssManager.createContext(serviceCredentials);
gssContext.acceptSecContext(this.serviceTicket, 0, this.serviceTicket.length);
GSSName srcName = gssContext.getSrcName();
return srcName.toString;
}
La connexion dans JavaClass.java ok, donc je suis en supposant que la connexion.conf est ok. Sur "GSSCredential serviceCredentials = gssManager.createCredential(..." dans le ServiceTicketDecoder.java l'exception suivante est générée:
java.security.PrivilegedActionException: GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos Key)
Je ne suis pas sûr si c'est la bonne approche. Aussi, je ne sais pas ce que la valeur de la "Chaîne de service" doit être ou comment obtenir cette information. Pouvez-vous m'aider?
EDIT:
connexion.conf
ServicePrincipalLoginContext
{
com.sun.security.auth.module.Krb5LoginModule
required
principal="HTTP/[email protected]"
doNotPrompt=true
useTicketCache=true
keyTab="C:/server-http.keytab"
debug=true;
};
J'ai reçu un fichier keytab. Apparemment, le HTTP/certains.serveur.com compte de l'utilisateur a déjà un service de compte principal. J'ai maintenant un problème sur JavaClass.java à la lc.login():
javax.security.auth.login.LoginException: KDC has no support for encryption type (14)
Caused by: KrbException: KDC has no support for encryption type (14)
Caused by: KrbException: Identifier doesn't match expected value (906)
Le fichier keytab est chiffré avec des-cbc-md5 et j'ai suivantes définies dans le rcond.fichier conf:
[libdefaults]
default_realm = MY.DOMAIN.COM
default_tkt_enctypes = des-cbc-md5
default_tgs_enctypes = des-cbc-md5
Si je change la valeur par défaut enctypes, par exemple aes128-cts, j'obtiens l'exception suivante:
javax.security.auth.login.LoginException: Do not have keys of types listed in default_tkt_enctypes available; only have keys of following type: DES CBC mode with MD5
Je ne comprends pas ce qui est faux...
OriginalL'auteur user1982861 | 2013-01-16
Vous devez vous connecter pour publier un commentaire.
Kerberos est un de tiers de confiance système de sécurité: le jeton de sécurité que vous recevez de la part du client est decryptable que par vous-même, et sans entrer en contact avec toute Kerberos serveurs d'infrastructure (tels que le KDC). Vous êtes sur la bonne voie; cependant, il semble que vous êtes absent de cette pièce de fond Kerberos connaissances pour vous guider dans votre recherche.
La façon d'y parvenir est que sur le serveur vous avez besoin d'un keytab fichier qui contient votre serveur de clé secrète. Le serveur Kerberos (Microsoft Windows Server, je présume), doit avoir un principal de service compte créé pour votre service. Un administrateur peut vous fournir avec le fichier keytab généré pour ce compte, qui contiendra la clé secrète.
Vous devez ensuite configurer le serveur pour trouver ce fichier keytab; il est utilisé dans le server-side step impliquant
LoginContext.login
. Votre code qui accepte le contexte de sécurité doit être exécuté à l'intérieur d'undoPrivileged
segment de code au sein de laquelle votre côté serveur les informations d'identification sont en effet.Changer le cryptage du fichier keytab corrigé le problème et tout fonctionne maintenant. Merci!!!!!
OriginalL'auteur Marko Topolnik
Si tout ce que vous voulez, c'est le nom de l'utilisateur il y a un moyen plus facile.
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getUserPrincipal()
http://docs.oracle.com/javase/7/docs/api/java/security/Principal.html
OriginalL'auteur keredson