[英]Dealing with long bearer tokens from webapi by providing a surrogate token
我正在使用ASP.NET WebApi 2使用聲明身份驗證構建Web api,我的用戶可以擁有大量的聲明。 由於大量聲明,承載令牌迅速增長非常大,因此我試圖找到一種返回更短的承載令牌的方法。
到目前為止,我發現我可以為OAuth選項OAuthAuthorizationServerOptions.AccessTokenProvider
屬性提供IAuthenticationTokenProvider
:
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(12),
AccessTokenProvider = new GuidProvider() // <-- here
};
這讓我有機會攔截AuthenticationTicket
並將其藏起來,用更簡單的東西取而代之 - 在我的例子下面是一個散列的guid。 (注意:目前這個類只包含一個ConcurrentDictionary<string,AuthenticationTicket>
和我的會話 - 在一個真實世界的例子中,我打算將會話存儲在一些持久存儲中)
public class GuidProvider : IAuthenticationTokenProvider
{
private static ConcurrentDictionary<string, AuthenticationTicket> tokens
= new ConcurrentDictionary<string, AuthenticationTicket>();
public void Create(AuthenticationTokenCreateContext context)
{
throw new NotImplementedException();
}
public async System.Threading.Tasks.Task CreateAsync(AuthenticationTokenCreateContext context)
{
var guid = Guid.NewGuid().ToString();
var ticket = Crypto.Hash(guid);
tokens.TryAdd(ticket, context.Ticket);
context.SetToken(ticket);
}
public void Receive(AuthenticationTokenReceiveContext context)
{
throw new NotImplementedException();
}
public async System.Threading.Tasks.Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
AuthenticationTicket ticket;
if (tokens.TryGetValue(context.Token, out ticket))
{
if (ticket.Properties.ExpiresUtc.Value < DateTime.UtcNow)
{
tokens.TryRemove(context.Token, out ticket);
}
context.SetTicket(ticket);
}
}
}
所以我的問題:
另外需要注意的是,我打算支持刷新令牌,實際上上面的示例是從使用這種機制的示例中提取的刷新令牌 - 除了刷新令牌它們似乎是單用的,因此ReceiveAsync
方法通常會一直刪除ConcurrentDictionary
提供的刷新令牌,我不完全確定我理解為什么?
我建議不要這樣做,因為您最終要將身份驗證票證存儲到數據庫或Redis服務器中,這里的抽獎表示每個請求包含一個不記名令牌,您將檢查此永久存儲以便解決Guid並再次獲得機票以構建它。
我建議您使用JSON Web Token JWT而不是默認的承載訪問令牌格式,為此,您需要在OAuthAuthorizationServerOptions
屬性Provider
中實現自定義訪問令牌格式CustomOAuthProvider
,如下所示:
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
//For Dev enviroment only (on production should be AllowInsecureHttp = false)
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/oauth2/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new CustomOAuthProvider(),
AccessTokenFormat = new CustomJwtFormat("http://jwtauthzsrv.azurewebsites.net")
};
我注意到,對JWT令牌添加更多聲明不會像默認訪問令牌格式那樣大幅增加其大小。
在每個內部具有不同聲明的2個JWT的樣本下面,第二個JWT比第一個僅大50個字符大。 我建議你使用jwt.io來檢查每個的編碼內容First JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzMyNywibmJmIjoxNDE4NjQ1NTI3fQ.vH9XPtjtAv2-6SwlyX4fKNJfm5ZTVHd_9a3bRgkA_LI
第二次JWT(更多聲明):
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6InRhaXNlZXIiLCJzdWIiOiJ0YWlzZWVyIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciIsIlN1cGVydmlzb3IxIiwiU3VwZXJ2aXNvcjIiLCJTdXBlcnZpc29yMyJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQxODY0NzQ1NiwibmJmIjoxNDE4NjQ1NjU2fQ.TFEGDtz1RN8VmCQu7JH4Iug0B8UlWDLVrIlvc-7IK3E
JWT格式正在成為發布OAuth 2.0承載令牌的標准方式,並且它將與刷新令牌授權一起使用。 但請記住,JWT只是簽名的令牌,而不是默認訪問令牌格式的情況,因此不要存儲機密數據。
我在bitoftech.net上寫了關於如何在ASP.NET Web API中使用JWT令牌以及在GIthub上使用實時演示API和源代碼的 詳細博客文章 ,請隨時查看它,如果您需要更多幫助,請告訴我。
祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.