Bonjour à tous,
J'essaie de me connecter à un instance managée de SQL Azure, ce que je parviens à faire en authentification
- SQL server,
- "Active Directory Interactive" (L'AADDS (Azure Active Directory) nous permet de nous authentifier sur le server SQL en MFA).
Mon problème : je souhaite me connecter à l'aide d'un token, grace l'attribut de connexion SQL_COPT_SS_ACCESS_TOKEN.
Voici le code que j'utilise pour récupérer mon token:
J'ai trouvé des exemples en Python, que j'ai essayé d'adapter. (Main_fdc est de type TFDConnection)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 procedure TExplorerForm.RESTDemandeToken; var vRESTClient : TRESTClient; VRESTREquest: TRESTRequest; vUrl, vGrantType, vTenantID, vClientID, vClientSecret, vRessource , vScope, vToken, vrefreshToken : String; begin vTenantID := 'TenantId'; vClientID := 'ClientId'; vClientSecret := 'ClientSecret'; vGrantType := 'client_credentials'; vRessource := 'https://database.windows.net/'; vScope := 'https://management.azure.com/.default'; vUrl := 'https://login.microsoftonline.com/' + vTenantID + '/oauth2/v2.0/token'; vRESTClient := TRESTClient.Create(vUrl); try ConfigureProxy(vRESTClient); VRESTREquest := TRESTRequest.Create(vRESTClient); VRESTREquest.Method := TRESTRequestMethod.rmPOST; VRESTREquest.Params.AddItem('grant_type', vGrantType, TRESTRequestParameterKind.pkGETorPOST, [], TRESTContentType.ctAPPLICATION_X_WWW_FORM_URLENCODED); VRESTREquest.Params.AddItem('client_id', vClientID, TRESTRequestParameterKind.pkGETorPOST, [], TRESTContentType.ctAPPLICATION_X_WWW_FORM_URLENCODED); VRESTREquest.Params.AddItem('scope', vScope, TRESTRequestParameterKind.pkGETorPOST, [], TRESTContentType.ctAPPLICATION_X_WWW_FORM_URLENCODED); VRESTREquest.Params.AddItem('client_secret', vClientSecret, TRESTRequestParameterKind.pkGETorPOST, [], TRESTContentType.ctAPPLICATION_X_WWW_FORM_URLENCODED); VRESTREquest.Params.AddItem('ressource', vRessource, TRESTRequestParameterKind.pkGETorPOST, [], TRESTContentType.ctAPPLICATION_X_WWW_FORM_URLENCODED); try VRESTREquest.Execute; except ShowMessage('Problème sur la requête RESTDemandeToken'); end; if VRESTREquest.Response.StatusCode = 200 then begin if not vRESTRequest.Response.GetSimpleValue('access_token', fToken) then ShowMessage('La réponse ne comprend pas de Token'); end; fTime := IncSecond(Now, 3599); Token_edt.Text := pToken; finally vRESTClient.Free end; end;
Mais j'ai un "Login failed for user ''."
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 procedure TExplorerForm.BeforeConnect(Sender: TObject); var vLen, vIdx : integer; vLen2 : LongWord; vToken, vToken_s : string; vToken_b : string; vODBCAdv : string; begin inherited; // test "ODBCAdvanced" SQL_COPT_SS_ACCESS_TOKEN (=1256) vToken_s := pToken; // Le jeton "database.windows.net" vLen := length(vToken_s); SetLength(vToken_b,vLen*2); for var i:=1 to vLen do begin vToken_b[(i*2)-1] := vToken_s[i]; vToken_b[i*2] := #0; end; vLen2 := Length(vToken_b); // ODBCAdvanced = attributs de connexion "before" de python ? vODBCAdv := 'ODBCAdvanced=1256=' + vLen2.ToHexString(4) + vToken_b; vIdx := Main_fdc.Params.IndexOfName('ODBCAdvanced'); if vIdx=-1 then vIdx := Main_fdc.Params.Add('ODBCAdvanced='); Main_fdc.Params[vIdx] := vODBCAdv; // Doc Microsoft stipule qu'il ne faut pas d'Authentication, UID, PWD et Trusted connexion pour SQL_COPT_SS_ACCESS_TOKEN vIdx := Main_fdc.Params.IndexOfName('User_Name'); if vIdx> -1 then Main_fdc.Params.Delete(vIdx); vIdx := Main_fdc.Params.IndexOfName('Password'); if vIdx> -1 then Main_fdc.Params.Delete(vIdx); vIdx := Main_fdc.Params.IndexOfName('Trusted_Connection'); if vIdx> -1 then Main_fdc.Params.Delete(vIdx); // n'est pas dans les Params de FiredDac, mais figure bien dans la chaine de connexion finale // voir : FireDac.Phys.ODBCWrapper - TODBCConnction.Connect end;
Voici un extrait de la chaine de connexion finale
Je me pose plein de questions :DRIVER=ODBC Driver 17 for SQL Server;Server=xxxxxx;Database=xxxxx;WSID=xxxxx;Trusted_Connection=No;Encrypt=Yes;APP=xxx;1256=0A0Ee#0y#0J#00#0e...
- Le format attendu par SQL server pour le type SQL_IS_POINTER est-il satisfait par la partie "vLen2.ToHexString(4)" (0A0E) ?
- Nous n'avons pas la main sur la chaine de connexion finale (par exemple Trusted_Connection=No est forcée), est-ce le bon moyen, je suis perturbé le "attrs_before" de python
-
Code : Sélectionner tout - Visualiser dans une fenêtre à part db = create_engine(SAconnString, connect_args={'attrs_before': {SQL_COPT_SS_ACCESS_TOKEN:tokenstruct}})
- que j'ai interprété par un complément "ODBCAdvanced", mais cela peut-il convenir pour envoyer l'attribut SQL_COPT_SS_ACCESS_TOKEN ?
Bref, si quelqu'un s'est déjà frotté au sujet ou a une vue plus expérimentée que la mienne sur le sujet, toute aide serait vraiment bien accueillie
Infos complémentaires :
le lien microsoft pour SQL_COPT_SS_ACCESS_TOKEN
et exemple python
Merci
Renaud
Partager