2014-12-31 26 views
5

Czy stwierdzenie w tytule jest poprawne? Opieram pytanie na pracy wykonanej przez Taisera Joudeha (dzięki za twoją pracę na ten temat, btw) pod numerem http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/.Odświeżanie tokenów w oauth2 nie powinno być zastępowane przy otrzymywaniu nowego tokena dostępu

Jeśli rozumiem zachowanie odświeżania żetony poprawnie, kiedy wygasa token dostępu, powinniśmy wezwać symboliczny punkt końcowy naszego serwera uwierzytelniającego z czymś jak

'grant_type=refresh_token&refresh_token=' + token 

i będziemy wracać nowy token dostępu. Żądanie to będzie zawierać znacznik odświeżania jako część ładunku, ale czy ten token odświeżania nie powinien być tym samym, którego właśnie użyliśmy? A przynajmniej powinien mieć to samo wygaśnięcie? Jeśli nie, to naprawdę, życie odświeżania jest nieskończone.

Oto testy frisby.js, których oczekuję, ale przy użyciu implementacji Taiseera dla Web Api 2, ostateczne oczekiwanie kończy się niepowodzeniem. Dostajemy nowy token odświeżania z nowym wydaniem tego tokena.

'use strict'; 

var frisby = require('frisby'); 
var config = require('../test-config.json'); 

var args = config[process.env.test || 'local']; 
var host = args.host, 
    clientId = args.clientId, 
    usr = args.user1, 
    pwd = args.password1; 

frisby.create('Try and fail to get a protected resource') 
    .get(host + '/api/test') 
    .expectStatus(401) 
    .expectHeaderContains('WWW-Authenticate', 'bearer') 
    .toss(); 

frisby.create('Log in and get a protected resource') 
    .post(host + '/token', { 
     grant_type: 'password', 
     username: usr, 
     password: pwd, 
     client_id: clientId 
    }) 
    .expectJSONTypes({ 
     access_token: String, 
     token_type: String, 
     expires_in: Number, 
     userName: String, 
     refresh_token: String, 
     'as:client_id': String, 
     '.issued': String, 
     '.expires': String 
    }) 
    .expectJSON({ 
     token_type: 'bearer', 
     userName: '[email protected]' 
    }) 
    .afterJSON(function (json) { 
     frisby.create('and now get protected resource with attached bearer token') 
      .get(host + '/api/test', { 
       headers: { 'Authorization': 'Bearer ' + json.access_token } 
      }) 
      .expectStatus(200) 
      .toss(); 
     frisby.create('and try to get a new access token with our refresh token') 
      .post(host + '/token', { 
       grant_type: 'refresh_token', 
       refresh_token: json.refresh_token, 
       client_id: clientId 
      }) 
      .afterJSON(function (json2) { 
       //we should receive a new access token 
       expect(json.access_token).not.toEqual(json2.access_token); 
       //but shouldn't the refresh token remain the same until *it* expires? 
       expect(json.refresh_token).toEqual(json2.refresh_token); 
      }) 
      .toss(); 
    }) 
    .toss(); 

Odpowiedz

5

są w 100% poprawne, obecna implementacja odświeżania token przesuwne wygaśnięcia tokena odświeżania, ponieważ z każdym użyciem grant_type = refresh_token wydajemy nowy token dostępu i odświeżyć symboliczny identyfikator, i to było idealne miejsce dla mój przypadek, ponieważ chcę, aby użytkownik był zalogowany na zawsze tak długo, jak korzysta z aplikacji, jeśli nie używał aplikacji przez okres dłuższy niż data wygaśnięcia tokena odświeżania, wówczas otrzyma 401, gdy spróbuje uzyskaj nowy token dostępu za pomocą odświeżającego tokena.

Aby zmienić to zachowanie, należy wydać tylko jeden identyfikator tokena odświeżania i zwrócić ten sam identyfikator, gdy użytkownik prosi o nowy token dostępu przy użyciu tokena odświeżania. Możesz to zrobić, dostosowując logikę biznesową w tej metodzie.

+1

Dzięki, Taiseer. Te rzeczy nie są łatwe, szczególnie gdy struktura Katana robi tak wiele "magii" w naszym imieniu. Wciąż pewnie lepiej niż pisać to sami. Pchnęłam moją pracę do repo - dostawca odświeżania jest tutaj: https://github.com/finleysg/stats-api/blob/master/StatsApi/Providers/RefreshTokenProvider.cs. Bez wątpienia wciąż naiwny i niepoprawny, ale moje drobne testy mijają. Czy martwisz się w ogóle logowaniem? Mam prostą implementację w kontrolerze konta, która usuwa wszystkie tokeny odświeżania dla użytkownika podczas akcji wylogowania. – Stuart

+0

@Taiseer Joudeh, jeśli użytkownik nie użył aplikacji przez okres dłuższy niż data ważności znacznika odświeżenia, wtedy otrzyma 401, gdy spróbuje uzyskać nowy token dostępu za pomocą odświeżającego tokena. Aby zmienić to zachowanie, musisz wystawia tylko pojedynczy identyfikator tokena odświeżania i zwraca ten sam identyfikator, gdy użytkownik prosi o nowy token dostępu za pomocą odświeżającego tokena. Jak mogę to zrobić? Chcę również, aby użytkownik był zalogowany na zawsze. Możesz pokazać kilka przykładów tego w ochrona sprężyny oauth2. – KJEjava48