更新时间:2022-12-06 13:03:23
值得注意的是,您不需要访问密钥即可解密身份验证cookie.您只需要使用通过正确的用途参数和子用途参数创建的正确的IDataProtector
.
基于CookieAuthenticationMiddleware
源代码
Based on the CookieAuthenticationMiddleware
source code https://github.com/aspnet/Security/blob/rel/1.1.1/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationMiddleware.cs#L4 it looks like the purpose you need to pass is typeof(CookieAuthenticationMiddleware)
. And since they are passing additional parameters to the IDataProtector
you will need to match them. So this line of code should get you an IDataProtector
that can be used to decrypt the authentication cookie:
var dataProtector = provider.CreateProtector(typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationScheme, "v2");
请注意,在这种情况下,Options.AuthenticationScheme
只是"MyCookie",因为这是在startup.cs文件的Configure
方法中设置的.
Note thatOptions.AuthenticationScheme
is just "MyCookie" in this case since that's what it was set to in the Configure
method of the startup.cs file.
以下是用于以两种不同方式解密身份验证cookie的示例操作方法:
Here is an example action method for decrypting your authentication cookie two different ways:
public IActionResult DecryptCookie() {
//Get the encrypted cookie value
string cookieValue = HttpContext.Request.Cookies["MyCookie"];
//Get a data protector to use with either approach
var dataProtector = provider.CreateProtector(typeof(CookieAuthenticationMiddleware).FullName, "MyCookie", "v2");
//Get the decrypted cookie as plain text
UTF8Encoding specialUtf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
byte[] protectedBytes = Base64UrlTextEncoder.Decode(cookieValue);
byte[] plainBytes = dataProtector.Unprotect(protectedBytes);
string plainText = specialUtf8Encoding.GetString(plainBytes);
//Get the decrypted cookie as a Authentication Ticket
TicketDataFormat ticketDataFormat = new TicketDataFormat(dataProtector);
AuthenticationTicket ticket = ticketDataFormat.Unprotect(cookieValue);
return View();
}
此方法使用称为provider
的IDataProtectionProvider
,该IDataProtectionProvider
是构造函数注入的.
This method uses an IDataProtectionProvider
called provider
that is constructor injected.
如果要在应用程序之间共享cookie,则可以决定将数据保护密钥保留在目录中.这可以通过将以下内容添加到startup.cs文件的ConfigureServices
方法中来完成:
If you want to share cookies between applications then you might decide to persist the data protection keys to a directory. This can be done by adding the following to the ConfigureServices
method of the startup.cs file:
services.AddDataProtection().PersistKeysToFileSystem(
new DirectoryInfo(@"C:\temp-keys\"));
请小心,因为密钥未加密,因此您有责任保护它们!!!仅在绝对必要时(或如果您只是想了解系统的工作方式),才将键保留在目录中.您还 需要指定使用这些键的cookie DataProtectionProvider
.可以借助startup.cs类的Configure
方法中的UseCookieAuthentication
配置来完成,如下所示:
BE CAREFUL though because the keys are not encrypted so it's up to you to protect them!!! Only persist the keys to a directory if you absolutely must, (or if you are just trying to understand how the system works). You will also need to specify a cookie DataProtectionProvider
that uses those keys. This can be done with the help of the UseCookieAuthentication
configuration in the Configure
method of the startup.cs class like so:
app.UseCookieAuthentication(new CookieAuthenticationOptions() {
DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"C:\temp-keys\")),
AuthenticationScheme = "MyCookie",
CookieName = "MyCookie",
LoginPath = new PathString("/Home/Login"),
AccessDeniedPath = new PathString("/Home/AccessDenied"),
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
完成该配置.现在,您可以使用以下代码解密身份验证Cookie:
With that configuration done. You can now decrypt the authentication cookie with the following code:
public IActionResult DecryptCookie() {
ViewData["Message"] = "This is the decrypt page";
var user = HttpContext.User; //User will be set to the ClaimsPrincipal
//Get the encrypted cookie value
string cookieValue = HttpContext.Request.Cookies["MyCookie"];
var provider = DataProtectionProvider.Create(new DirectoryInfo(@"C:\temp-keys\"));
//Get a data protector to use with either approach
var dataProtector = provider.CreateProtector(typeof(CookieAuthenticationMiddleware).FullName, "MyCookie", "v2");
//Get the decrypted cookie as plain text
UTF8Encoding specialUtf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
byte[] protectedBytes = Base64UrlTextEncoder.Decode(cookieValue);
byte[] plainBytes = dataProtector.Unprotect(protectedBytes);
string plainText = specialUtf8Encoding.GetString(plainBytes);
//Get teh decrypted cookies as a Authentication Ticket
TicketDataFormat ticketDataFormat = new TicketDataFormat(dataProtector);
AuthenticationTicket ticket = ticketDataFormat.Unprotect(cookieValue);
return View();
}
您可以在此处了解有关后一种情况的更多信息: https://docs.microsoft.com/zh-CN/aspnet/core/security/data-protection/compatibility/cookie共享
You can learn more about this latter scenario here: https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/compatibility/cookie-sharing