Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> logowanie do aplikacji za pomocą Tokena
inomi13
post 8.11.2022, 21:23:24
Post #1





Grupa: Zarejestrowani
Postów: 95
Pomógł: 0
Dołączył: 16.08.2017

Ostrzeżenie: (0%)
-----


Do tej pory miałem zadanie cron, które wykonywało się raz dziennie i pobierało zawartość skrzynki za pomocą imap_open. W związku z wyłączeniem przez Microsoft uwierzytelnienia za pomocą hasła oraz że PHP nie posiada wbudowanej funkcji obsługującej Oauth2 w imapi'e skorzystałem z gotowego rozwiązania https://github.com/Webklex/php-imap i loguje się za pomocą Oauth2.

Problem polega na tym że ważność tokena to 1 godzina więc zadanie cron w tym wypadku odpada. Zrobiłem partyzanckie rozwiązanie tzn. loguje się przez przeglądarkę do konta Microsoft, następnie w sesji przesyłam otrzymany get adres e-mail oraz token do pliku konfiguracyjnego php-imap, a następnie dodałem meta
  1. <meta http-equiv="refresh" content = "3600" />
, które odświeża stronę przed wygaśnięciem tokena.

Proszę o sugestie jak powinno to sensownie działać, może odświeżenie tokena...
Go to the top of the page
+Quote Post
ohm
post 9.11.2022, 11:55:28
Post #2





Grupa: Zarejestrowani
Postów: 619
Pomógł: 143
Dołączył: 22.12.2010

Ostrzeżenie: (0%)
-----


A nie ma zadnego endpointa api zebys mogl odpytac po token?
Go to the top of the page
+Quote Post
inomi13
post 9.11.2022, 18:58:32
Post #3





Grupa: Zarejestrowani
Postów: 95
Pomógł: 0
Dołączył: 16.08.2017

Ostrzeżenie: (0%)
-----


Po wywołaniu poniższego kodu i zalogowaniu kontem Microsoft, wyciągam z URL'a token, który następnie obrabiam Curl'em, a następnie dekoduje je za pomocą json_decode.

Poniższy URL zawiera ważność tokena expires_in, więc bez odświeżenia tokena logout nastąpi po 1 godzine. Pytanie do znawców, w którą stronę iść aby wygenerować refresh tokens? Jeżeli ktoś ma jakieś przykłady to też chętnie przyjmę do analizy.


https://xxxxxxxxxxx?access_token=zb2Z0LmNvbSIsInV0aSI6Im9QRG9YajFrZVVDXXXXXX&token_type=Bearer&expires_in=4750&scope=https%3a%2f%2foutlook.office.com%2fIMAP.AccessAsUser.All+https%3a%2f%2foutlook.office.com%2fUser.Read&state=7f72451bd636d3c3d2030exxxxxxxx&session_state=4935654d-c68f-4df1-bc0d-xxxxxxxxxx



  1.  
  2. $appid = "XXXXXXXXXXXXXXXXXXX";
  3. $secret = "XXXXXXXXXXXXXXXXXXX";
  4. $loginUrl ="https://login.microsoftonline.com/XXXXXXXXXXXXXXXX/oauth2/v2.0/authorize";
  5.  
  6. $_SESSION['state'] = session_id();
  7.  
  8. echo '<a href="?action=login">Zaloguj</a>';
  9.  
  10. if($_GET['action'] == 'login')
  11. {
  12. $params = array ('client_id' => $appid,
  13.  
  14. 'redirect_uri' => 'https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  15.  
  16. 'response_type' => 'token',
  17.  
  18. 'scope' => 'https://outlook.office.com/IMAP.AccessAsUser.All',
  19.  
  20. 'state' => $_SESSION['state']);
  21.  
  22. header ('Location: '.$login_url.'?'.http_build_query ($params));
  23. }


Ten post edytował inomi13 9.11.2022, 19:45:09
Go to the top of the page
+Quote Post
vokiel
post 9.11.2022, 22:01:42
Post #4





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

Ostrzeżenie: (0%)
-----


Zwykle w Oauth2 jest tak, że jak wygenerujesz access token to wraz z nim dostajesz też refresh token, który ma długi czas życia (albo nie wygasa do czasu odwołania). Za po mocą refresh tokena generujesz sobie nowy access token.
Autoryzację przez użytkownika robisz zwykle tylko raz.

Tu masz opisane
https://learn.microsoft.com/en-us/azure/act...-auth-code-flow
https://learn.microsoft.com/en-us/azure/act.../refresh-tokens
https://learn.microsoft.com/en-us/azure/act...op/v2-app-types


--------------------
Go to the top of the page
+Quote Post
inomi13
post 10.11.2022, 08:02:02
Post #5





Grupa: Zarejestrowani
Postów: 95
Pomógł: 0
Dołączył: 16.08.2017

Ostrzeżenie: (0%)
-----


I tutaj jest właśnie problem ponieważ nie mam pojęcia dlaczego w URL'u nie otrzymuje refresh_token. Po stronie Azure mam wszystko skonfigurowane według wytycznych Microsoft.
Go to the top of the page
+Quote Post
vokiel
post 10.11.2022, 10:27:53
Post #6





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

Ostrzeżenie: (0%)
-----


Chyba nie czytałeś tej dokumentacji. Masz tam przecież ładny diagram z całym flow https://learn.microsoft.com/en-us/azure/act...op/v2-app-types

Wpierw sięgasz do /oauth2/authorize, potem do /oauth2/token


--------------------
Go to the top of the page
+Quote Post
inomi13
post 10.11.2022, 21:01:46
Post #7





Grupa: Zarejestrowani
Postów: 95
Pomógł: 0
Dołączył: 16.08.2017

Ostrzeżenie: (0%)
-----


Obecnie zrobiłem taki bypass. Loguję się do konta Microsoft zapisuje token oraz nazwę użytkownika w pliku nazwa.php, następnie cronem wywołuje skrypt, który sprawdza czy w pliku nazwa.php istnieje token i czy token jest zgodny. Wtedy następuje wywoływanie
  1. header ('Location: '.$login_url.'?'.http_build_query ($params))
ale już nie z tokenem pobranym z Url'a tylko pobranym z pliku. Co nie zmienia faktu że bez refresh_token po godzinie i tak nastąpi logout.

Ten post edytował inomi13 10.11.2022, 22:00:14
Go to the top of the page
+Quote Post
vokiel
post 11.11.2022, 18:52:08
Post #8





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

Ostrzeżenie: (0%)
-----


Tylko po co robisz jakiś bypass skoro możesz zrobić to zgodnie z dokumentacją?

1. Generujesz link do logowania użytkownika: /authorize.
2. Dostajesz auth_code, którego używasz w requeście do /token
3. W odpowiedzi dostajesz access_token i refresh_token https://learn.microsoft.com/en-us/azure/act...sful-response-2
4. Zapisujesz sobie gdzieś tokeny wraz z czasem wygasania access_tokena.
5. Dalej w aplikacji sprawdzasz czy aktualny access_token jest jeszcze aktywny, jeśli tak to go używasz.
6. Jeśli nie, to bierzesz refresh_token i pobierasz nowy access_token.


--------------------
Go to the top of the page
+Quote Post
inomi13
post 13.11.2022, 07:05:58
Post #9





Grupa: Zarejestrowani
Postów: 95
Pomógł: 0
Dołączył: 16.08.2017

Ostrzeżenie: (0%)
-----


Zrobiłem tak jak sugerowałeś jednak nadal nie wiem dlaczego nie otrzymuje refresh_tokena

  1. $endpoint_authorize = 'https://login.microsoftonline.com/xxxxxxxxxxxxxxxxxxxxxxxxx/oauth2/v2.0/authorize';
  2. $endpoint_token = 'https://login.microsoftonline.com/xxxxxxxxxxxxxxxxxxxxxxxxx/oauth2/v2.0/token';
  3. $redirect_uri = 'https://xxxxxxxxxxxxxxxxxxxxxxxxx.php';
  4.  
  5. $client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxx';
  6. $client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxx';
  7.  
  8. $login = $endpoint_authorize.'?'.http_build_query([
  9. 'client_id' => $client_id,
  10. 'redirect_uri' => $redirect_uri,
  11. 'scope' => 'https://outlook.office.com/IMAP.AccessAsUser.All',
  12. 'response_type' => 'code',
  13. ]);
  14.  
  15. echo '<a href = "'.$login.'">Loguj</a>';
  16.  
  17. if(isset($_GET['code']))
  18. {
  19. $code = $_GET['code'];
  20.  
  21. $ch = curl_init();
  22. curl_setopt($ch, CURLOPT_URL,$endpoint_token);
  23. curl_setopt($ch, CURLOPT_POST, TRUE);
  24. curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
  25. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  26. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
  27. 'code' => $code,
  28. 'client_id' => $client_id,
  29. 'client_secret' => $client_secret,
  30. 'redirect_uri' => $redirect_uri,
  31. 'grant_type' => 'authorization_code',
  32. ]));
  33. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  34. $response = curl_exec($ch);
  35. curl_close($ch);
  36.  
  37. echo '<pre>';
  38. print_r($response);
  39. echo '</pre>';
  40. }


Wynik dostaje:
"token_type":"Bearer",
"scope":"https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/User.Read",
"expires_in":3749,
"ext_expires_in":3749,
"access_token":"eyw......."


Ponowne odświeżenie strony daje wynik

{"error":"invalid_grant","error_description":"AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.\r\nTrace ID: xxxx-6c31-40c7-aa47-74b745582300\r\nCorrelation ID: xxxxx-8ecd-40da-a2d4-132f3be38b0a\r\nTimestamp: 2022-11-12 19:30:06Z","error_codes":[54005],"timestamp":"2022-11-12 19:30:06Z","trace_id":"xxxxx-6c31-40c7-aa47-74b745582300","correlation_id":"xxxxx-8ecd-40da-a2d4-132f3be38b0a"}

Znalazłem rozwiązanie mojego problemu, który polegał na złym ustawieniu zakresu tzn. jeżeli chcemy otrzymać refresh_token to zakres musi kończyć się offline_access. Oczywiście dostęp do offline_access musi być również ustawiony po stronie Azure.

Ten post edytował inomi13 12.11.2022, 20:31:59
Go to the top of the page
+Quote Post
ZenekN
post 15.11.2022, 07:24:08
Post #10





Grupa: Zarejestrowani
Postów: 418
Pomógł: 5
Dołączył: 7.08.2012

Ostrzeżenie: (0%)
-----


o jaki zakres chodzi ?
Go to the top of the page
+Quote Post
viking
post 15.11.2022, 10:19:30
Post #11





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


O scope.


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 27.04.2024 - 16:26