我有一个 webforms 网站正在调用我们正在开发的新 MVC6 网站。用户将像往常一样使用表单例份验证在 webforms 网站上登录,然后被重定向到新的 MVC6 网站。我知道在 MVC6 中我应该使用 Cookie 身份验证但无法使用它来解密 cookie。我怀疑它归结于 web.config 和 machinekey 的变化,但我真的卡住了。
这是我所做的。
我已经设置cookie认证如下
app.UseCookieAuthentication(options =>
{
options.CookieName = "MyWebformsCookie";
options.AutomaticAuthenticate = true;
options.AuthenticationScheme = "Cookies";
options.TicketDataFormat = new MySecureDataFormat();
options.DataProtectionProvider = new MyDataProtectionProvider();
//options.CookieDomain = "localhost";
});
类如下
public class MySecureDataFormat : ISecureDataFormat<AuthenticationTicket>
{
public string Protect(AuthenticationTicket data)
{
return string.Empty;
}
public string Protect(AuthenticationTicket data, string purpose)
{
return string.Empty;
}
public AuthenticationTicket Unprotect(string protectedText)
{
return null;
}
public AuthenticationTicket Unprotect(string protectedText, string purpose)
{
var ticket = FormsAuthentication.Decrypt(protectedText);
return null;
}
}
正在读取 cookie,并调用了 Unprotect 方法,但随后在 FormsAuthentication.Decrypt 方法上出现错误
System.Web.dll 中发生“System.Web.HttpException”类型的异常,但未在用户代码中处理
附加信息:无法验证数据。
Stack = at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType, Boolean signData) at System.Web.Security.FormsAuthentication.Decrypt(String encryptedTicket) at WebApplication.Mvc.MySecureDataFormat.Unprotect(String protectedText, String purpose) in C:\SVNCode\GlobalConnectV2\WebApplication.Mvc\Startup.cs:line 153
at Microsoft.AspNet.Authentication.Cookies.CookieAuthenticationHandler.d__9.MoveNext()
所以这让我相信它不是在读取机器 key 。我在 wwwroot 文件夹的 web.config 中有这个
<configuration>
<system.webServer>
...
</system.webServer>
<system.web>
<machineKey compatibilityMode="Framework20SP2" validation="SHA1" decryption="AES" validationKey="mykey" decryptionKey="dec" />
</system.web>
</configuration>
这适用于早期的 MVC 应用程序,但猜测在 MVC6 中发生了一些变化。我也尝试过以下但没有运气
services.ConfigureDataProtection(configure =>
{
configure.UseCryptographicAlgorithms(new Microsoft.AspNet.DataProtection.AuthenticatedEncryption.AuthenticatedEncryptionOptions()
{
EncryptionAlgorithm = Microsoft.AspNet.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_256_CBC,
ValidationAlgorithm = Microsoft.AspNet.DataProtection.AuthenticatedEncryption.ValidationAlgorithm.HMACSHA256
});
});
有什么建议吗?
最佳答案
我对在 ASP.NET 5 应用程序中使用 FormsAuthentication.Decrypt() 感到很不高兴。
最后,我根据可用的文档编写了一个解密例程,并查看了 Microsoft 为系统 Web 提供的引用源代码。
解密使用 SHA1 验证和 AES 加密的表单例份验证 cookie 所需的类可以在我的 GIST 上找到:https://gist.github.com/dazinator/0cdb8e1fbf81d3ed5d44
一旦有了这些,您就可以像以前一样创建自定义 TicketFormat:
public class FormsAuthCookieTicketFormat : ISecureDataFormat<AuthenticationTicket>
{
private LegacyFormsAuthenticationTicketEncryptor _Encryptor;
private Sha1HashProvider _HashProvider;
public FormsAuthCookieTicketFormat(string decryptionKey, string validationKey)
{
_Encryptor = new LegacyFormsAuthenticationTicketEncryptor(decryptionKey);
_HashProvider = new Sha1HashProvider(validationKey);
}
public string Protect(AuthenticationTicket data)
{
throw new NotImplementedException();
}
public string Protect(AuthenticationTicket data, string purpose)
{
throw new NotImplementedException();
}
public AuthenticationTicket Unprotect(string protectedText)
{
throw new NotImplementedException();
}
public AuthenticationTicket Unprotect(string protectedText, string purpose)
{
var ticket = _Encryptor.DecryptCookie(protectedText, _HashProvider);
var identity = new ClaimsIdentity("MyCookie");
identity.AddClaim(new Claim(ClaimTypes.Name, ticket.Name));
identity.AddClaim(new Claim(ClaimTypes.IsPersistent, ticket.IsPersistent.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Expired, ticket.Expired.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Expiration, ticket.Expiration.ToString()));
identity.AddClaim(new Claim(ClaimTypes.CookiePath, ticket.CookiePath));
identity.AddClaim(new Claim(ClaimTypes.Version, ticket.Version.ToString()));
// Add some additional properties to the authentication ticket.
var props = new AuthenticationProperties();
props.ExpiresUtc = ticket.Expiration.ToUniversalTime();
props.IsPersistent = ticket.IsPersistent;
var principal = new ClaimsPrincipal(identity);
var authTicket = new AuthenticationTicket(principal, props, CookieDetails.AuthenticationScheme);
return authTicket;
}
然后像这样连接起来:
var formsCookieFormat = new FormsAuthCookieTicketFormat(_DecryptionKeyText, _ValidationKeyText);
app.UseCookieAuthentication(options =>
{
// shortened for brevity...
options.TicketDataFormat = formsCookieFormat ;
options.CookieName = "MyCookie";
});
关于c# - MVC6 从另一个网站解密表单例份验证 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34265117/
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案
在Ruby中可以使用哪些替代方法来ping一个ip地址?标准库“ping”库的功能似乎非常有限。我对在这里滚动我自己的代码不感兴趣。有没有好的gem?我应该接受它并忍受它吗?(我在Linux上使用Ruby1.8.6编写代码) 最佳答案 net-ping值得一看。它允许TCPping(如标准rubyping),但也允许UDP、HTTP和ICMPping。ICMPping需要root权限,但其他则不需要。 关于ruby-Pingruby网站?,我们在StackOverflow上找到一个类
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir