【发布时间】:2017-08-08 03:00:14
【问题描述】:
让我们考虑一个众所周知的 ASP.NET Core 场景。首先我们添加中间件:
public void Configure(IApplicationBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationScheme = "MyCookie",
CookieName = "MyCookie",
LoginPath = new PathString("/Home/Login/"),
AccessDeniedPath = new PathString("/Home/AccessDenied/"),
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
//...
}
然后序列化一个主体:
await HttpContext.Authentication.SignInAsync("MyCookie", principal);
在这两个调用之后,一个加密的 cookie 将被存储在客户端。您可以在任何浏览器开发工具中看到 cookie(在我的情况下是分块的):
使用来自应用程序代码的 cookie 不是问题(也不是问题)。
我的问题是:如何解密应用外的cookie?我想这需要一个私钥,如何获得它?
我查了docs,发现只有常用词:
这将创建一个加密的 cookie 并将其添加到当前 回复。配置期间指定的 AuthenticationScheme 必须 也可以在调用 SignInAsync 时使用。
在幕后使用的加密是 ASP.NET 的数据保护 系统。如果您在多台机器上托管,负载平衡或 使用网络场,那么您需要将数据保护配置为 使用相同的密钥环和应用程序标识符。
那么,是否可以解密身份验证 cookie,如果可以,如何解密?
更新 #1: 基于 Ron C great answer and comments,我最终得到了代码:
public class Startup
{
//constructor is omitted...
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection().PersistKeysToFileSystem(
new DirectoryInfo(@"C:\temp-keys\"));
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
AuthenticationScheme = "MyCookie",
CookieName = "MyCookie",
LoginPath = new PathString("/Home/Index/"),
AccessDeniedPath = new PathString("/Home/AccessDenied/"),
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
}
public class HomeController : Controller
{
public async Task<IActionResult> Index()
{
await HttpContext.Authentication.SignInAsync("MyCookie", new ClaimsPrincipal());
return View();
}
public IActionResult DecryptCookie()
{
var provider = DataProtectionProvider.Create(new DirectoryInfo(@"C:\temp-keys\"));
string cookieValue = HttpContext.Request.Cookies["MyCookie"];
var dataProtector = provider.CreateProtector(
typeof(CookieAuthenticationMiddleware).FullName, "MyCookie", "v2");
UTF8Encoding specialUtf8Encoding = new UTF8Encoding(false, true);
byte[] protectedBytes = Base64UrlTextEncoder.Decode(cookieValue);
byte[] plainBytes = dataProtector.Unprotect(protectedBytes);
string plainText = specialUtf8Encoding.GetString(plainBytes);
return Content(plainText);
}
}
不幸的是,这段代码总是在Unprotect 方法调用上产生异常:
Microsoft.AspNetCore.DataProtection.dll 中的 CryptographicException: 附加信息:有效负载无效。
我在几台机器上测试了这段代码的不同变体,但没有得到肯定的结果。可能我犯了一个错误,但是在哪里?
更新 #2: 我的错误是 DataProtectionProvider 尚未在 UseCookieAuthentication 中设置。再次感谢@RonC。
【问题讨论】:
-
你能用正确的代码更新你的答案吗?
-
@RonC 给出了接受的答案,而不是我。他的代码是正确的。
标签: security authentication cookies asp.net-core asp.net-core-mvc