2016-09-26 58 views
4

我有一個允許匿名用戶的ASP.NET Core MVC應用程序。這個程序是調用由身份服務器4.我已經創建了Identity Server的客戶端描述MVC應用程序(客戶端)的保護,給予其訪問API範圍這樣的ASP.NET Web API:使用客戶端證書持久化令牌的最佳實踐流程

new Client 
{ 
    ClientId = "my-mvc-client-app", 
    AllowedGrantTypes = GrantTypes.ClientCredentials, 

    RequireConsent = false, 
    ClientSecrets = new List<Secret> { new Secret("this-is-my-secret".Sha256()) }, 
    AllowedScopes = new List<string> 
    { 
     StandardScopes.OpenId.Name, 
     StandardScopes.Profile.Name, 
     StandardScopes.OfflineAccess.Name, 
     "my-protected-api" 
    }, 
    RedirectUris = new List<string> 
    { 
     "http://localhost:5009/signin-oidc", 
    } 
} 

在我的MVC應用程序,我使用TokenClient獲得令牌發出請求,以這樣的受保護的API時,我可以使用:

var disco = await DiscoveryClient.GetAsync("http://localhost:5010"); 
var tokenClient = new TokenClient(disco.TokenEndpoint, clientId, clientSecret); 
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("hrmts-test-candidate-api-scope"); 

這工作得很好,但我請求來自Identity Server的新令牌在每個請求上,這可能不是一個好主意。

處理令牌的最佳做法是什麼?我如何將它們保存在客戶端(MVC應用程序)上,以及如何處理刷新令牌以確保客戶端在必要時獲取新令牌?

回答

4

您需要將該客戶端包裝在某種託管服務(作爲單例)中,以便您可以在任何需要的地方使用它。我們有一個令牌組件用於服務器之間的服務器通信,遵循以下流程:

public class ServerTokenComponent 
{ 
    private TokenResponse Token { get; set; } 
    private DateTime ExpiryTime { get; set; } 
    public async Task<TokenResponse> GetToken() 
    { 
     //use token if it exists and is still fresh 
     if (Token != null) 
     { 
      if (ExpiryTime > DateTime.UtcNow) 
      { 
       return Token; 
      } 
     }  

     //else get a new token 
     var client = new TokenClient("myidpauthority.com","theclientId","thesecret") 
     var scopes = "for bar baz"; 

     var tokenResponse = await client.RequestClientCredentialsAsync(scopes); 

     if (tokenResponse.IsError || tokenResponse.IsHttpError) 
     { 
      throw new SecurityTokenException($"Could not retrieve token."); 
     } 

     //set Token to the new token and set the expiry time to the new expiry time 
     Token = tokenResponse; 
     ExpiryTime = DateTime.UtcNow.AddSeconds(Token.ExpiresIn); 

     //return fresh token 
     return Token; 
    } 
} 
+0

我喜歡這種方法,但是,如果這是作爲一個單身人士的範圍是這個實現線程安全和可重入安全嗎? – LugTread

2

IOW - 您需要以某種方式緩存該令牌。當您請求令牌時,您會在回覆中得到一個ExpiresIn - 這會告訴您令牌有效的時間。

另一種選擇是等到API返回401 - 然後請求新的令牌。

刷新令牌不與客戶端憑據流一起使用。