OVH Cloud OVH Cloud

identification sous windows

1 réponse
Avatar
Yoann Poizeau
Bonjour a tous,

mon application java utilise le système d'authentification windows pour
determiner si un utilisateur s'est connecté avec le bon password
pour l'instant j'utilisais la fonction "net use" de windows pour tester le
mot de passe mais le problème c'est que je me retrouve parfois avec l'erreur
suivante

Error = 1219\nL'erreur systäme 1219 s'est produite.\r\n\r\nPlusieurs
connexions . un serveur ou . une ressource partag,e par le màme utilisateur,
en utilisant plus d'un nom utilisateur, ne sont pas autoris,es. Supprimez
toutes les connexions pr,c,dentes

du coup je pense que ce n'est pas "net use" qu'il faut que j'utilise.

Est ce que l'un de vous connait un moyen de vérifier qu'un mot de passe Y et
bien celui d'un utilisateur X en java ou en ligne de commande

1 réponse

Avatar
Fabien

Est ce que l'un de vous connait un moyen de vérifier qu'un mot de passe Y et
bien celui d'un utilisateur X en java ou en ligne de commande


Je me suis amusé à faire ça avec la JNI, je crée une classe native :


=================================================================== public class NativeAuth {
/**
* Not instanciable
*/
private NativeAuth() {
}
/**
* Initialize native authentification sub-system
*/
public static void init() {
System.loadLibrary("libKaffirAuth");
}
/**
* Performs authentification of the user
* @param login User's login
* @param password User's password
* @return The user's natural name into the system or null
* @throws NativeAuthException If an error occurs on the OS
*/
public static native String loginUser(
String login, String password)
throws NativeAuthException;
...
}
===================================================================
Bon, trois petits points parce qu'elle fait autre chose...

Un coup de javah :
=================================================================== /*
* Class: st_fr_knf_kaffir_services_impl_auth_NativeAuth
* Method: loginUser
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_st_fr_knf_kaffir_services_impl_auth_NativeAuth_loginUser
(JNIEnv *, jclass, jstring, jstring);
===================================================================
J'implémente la fonction en C :

=================================================================== /*
* Class: st_fr_knf_kaffir_services_impl_auth_NativeAuth
* Method: loginUser
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
extern "C" jstring JNICALL
Java_st_fr_knf_kaffir_services_impl_auth_NativeAuth_loginUser
(JNIEnv *env, jclass self, jstring login, jstring password) {
bool errorúlse;
char errorBuffer[USERS_NAME_MAX_LENGTH];

if ((login==NULL)||(password==NULL)) {
jclass npe=env->FindClass(JAVA_NULL_POINTER_EXCEPTION);
env->ThrowNew(npe,"Null login or password");
return NULL;
}
const char* clogin=env->GetStringUTFChars(login,0);
const char* cpassword=env->GetStringUTFChars(password,0);
jstring naturalName=NULL;
if (verifyLoginInformation(clogin,cpassword)) {
char buffer[USERS_NAME_MAX_LENGTH];
if (getNaturalName(clogin,buffer,errorBuffer,USERS_NAME_MAX_LENGTH)==0) {
naturalName=env->NewStringUTF(buffer);
} else {
error=true;
}
}
env->ReleaseStringUTFChars(login,clogin);
env->ReleaseStringUTFChars(password,cpassword);
if (error) {
/*** Ici, une macro qui lance une exception JAVA ****/
THROW_JEXCEPTION(errorBuffer);
}
return naturalName;
}
===================================================================
Comme tu peux le vois, je m'appuis sur une librairie que j'ai développé
pour parler avec l'API Win32 de sécurité :

=================================================================== // Vérifie l'authentification système de l'utilisateur
// S'assurer que les utilisateurs autorisés à utiliser le serveur
d'application
// ont le privilège "Ouvrir une session localement"
bool verifyLoginInformation(const char* login, const char* password)
{
HANDLE hToken;
char llogin[USERS_NAME_MAX_LENGTH];
char lpassword[USERS_NAME_MAX_LENGTH];

strcpy(llogin,login);
strcpy(lpassword,password);
int
hr=LogonUser(llogin,".",lpassword,LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hToken);
if (hr==0)
{
#ifdef _DEBUG
printf("Error code=%dn",GetLastError());
#endif
return false;
}
else
{
#ifdef _DEBUG
printf("Authentification successfulln");
#endif
CloseHandle(hToken);
return true;
}
}

// Retrouve le nom naturel d'un utilisateur à partir de son login
// Retourne -1 si erreur et 0 si OK
int getNaturalName(const char* login, char* oNaturalName, char*
errorBuffer, size_t lgBuffer) {

LPUSER_INFO_2 user_structure=NULL;
WCHAR wlogin[USERS_NAME_MAX_LENGTH];

if
(MultiByteToWideChar(CP_ACP,0,login,-1,wlogin,USERS_NAME_MAX_LENGTH)==0) {
fillWin32ErrorMessage(GetLastError(),errorBuffer,lgBuffer);
return -1;
}
int ret=NetUserGetInfo(NULL,wlogin,2,(LPBYTE*)&user_structure);
if (ret==NERR_Success) {
if (user_structure!=NULL) {
if (WideCharToMultiByte(
CP_THREAD_ACP,0,user_structure->usri2_full_name,-1,
oNaturalName,USERS_NAME_MAX_LENGTH,NULL,NULL)==0)
{
fillWin32ErrorMessage(GetLastError(),errorBuffer,lgBuffer);
return -1;
}
NetApiBufferFree(user_structure);
return 0;
} else {
fillErrorBuffer("Le système a renvoyé des données
nulles",errorBuffer,lgBuffer);
return -1;
}
} else {
fillNetAPIErrorMessage((DWORD)ret,errorBuffer,lgBuffer);
return -1;
}
}
=================================================================== Sachant que "fillWin32ErrorMessage" sert juste à remonter des messages
d'erreurs...

Ca marche nickel, et tu peux faire ça en restant dans le monde libre :
la doc sur http://msdn.microsoft.com et comme compilo MinGW qui intègre
gcc pour Windows avec les libs Win32. Et en plus, il s'intègre super
bien dans Eclipse !

@+ Fabien