ASP.NET OAuth:解決refresh token無法重新整理access token的問題

來源:互聯網
上載者:User

標籤:

最近同事用iOS App調用Open API時遇到一個問題:在access token到期後,用refresh token重新整理access token時,伺服器響應"invalid_grant"錯誤;而在access token沒有到期的情況下,能正常重新整理access token。

先查看了一下OAuth規範中的“Refreshing an Expired Access Token”流程圖,以確認用戶端的操作流程有沒有問題。

問題發生在中的(G)操作步驟。iOS App就是按的流程進行操作的——在調用Open API時,如果伺服器響應access token無效,就用refresh token重新整理access token,用戶端的操作流程一點問題沒有。

於是將問題鎖定在服務端。打點寫日誌,發現refresh token重新整理access token時服務端先調用了IAuthenticationTokenProvider.ReceiveAsync(),然後調用了IOAuthAuthorizationServerProvider.GrantRefreshToken()方法。對應於我們的實現就是CNBlogsRefreshTokenProvider.ReceiveAsync()與CNBlogsAuthorizationServerProvider.GrantRefreshToken()。

查看ReceiveAsync()方法的實現代碼:

public override async Task ReceiveAsync(AuthenticationTokenReceiveContext context){    var refreshToken = await _refreshTokenService.Get(context.Token);    if (refreshToken != null)    {        context.DeserializeTicket(refreshToken.ProtectedTicket);                        await _refreshTokenService.Remove(context.Token);    }}

從上面的代碼可以得知,用refresh token重新整理access token,實際就是將儲存在資料庫中的ProtectedTicket反序列為包含access token的ticket,然後根據這個ticket產生access token返回給用戶端。而refreshToken.ProtectedTicket是在產生refresh token時由包含access token的ticket序列化產生的,refresh token無法重新整理access token,問題很可能就出在它身上。

於是查看產生refresh token部分的代碼——CNBlogsRefreshTokenProvider(繼承自AuthenticationTokenProvider)的CreateAsync()方法:

var refreshToken = new RefreshToken(){    Id = refreshTokenId,    ClientId = new Guid(clientId),    UserName = context.Ticket.Identity.Name    IssuedUtc = DateTime.UtcNow,    ExpiresUtc = DateTime.UtcNow.AddSeconds(Convert.ToDouble(refreshTokenLifeTime)),    ProtectedTicket = context.SerializeTicket()};context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;

當時一看代碼,立馬恍然大悟。應該是先設定IssuedUtc與ExpiresUtc,然後再SerializeTicket();實際被寫成了先SerializeTicket(),後設定IssuedUtc與ExpiresUtc。結果造成refreshToken.ProtectedTicket的到期時間不正確,從而無法重新整理access token。

解決方案很簡單,只需將context.SerializeTicket()移至設定Ticket的IssuedUtc與ExpiresUtc的代碼之後:

var refreshToken = new RefreshToken(){    Id = refreshTokenId,    ClientId = new Guid(clientId),    UserName = context.Ticket.Identity.Name    IssuedUtc = DateTime.UtcNow,    ExpiresUtc = DateTime.UtcNow.AddSeconds(Convert.ToDouble(refreshTokenLifeTime)),    };context.Ticket.Properties.IssuedUtc = refreshToken.IssuedUtc;context.Ticket.Properties.ExpiresUtc = refreshToken.ExpiresUtc;refreshToken.ProtectedTicket = context.SerializeTicket();

ASP.NET OAuth:解決refresh token無法重新整理access token的問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.