我一直在使用dotnet core来创建一个在Linux主机上的Kubernetes集群中运行的应用程序.在我测试时,它注意到在验证CSRF令牌时遇到异常,这是有道理的,因为我没有编辑机器密钥在每个实例上都是相同的.当我继续在web.config中设置机器密钥时,我注意到它将不再适用于.Net Core.
现在使用DataProtection API,机器密钥不再有效.我尝试将api实现到我的应用程序中,但是当我阅读时,我需要使用网络共享来交换所有实例之间的密钥我被震惊了.当然必须有一种更简单(更好)的方法来实现这一点,而不必依赖共享在线吗?
我试图在ConfigureServices方法的Startup类中设置以下内容:
services.AddDataProtection().SetApplicationName("DockerTestApplication");
我以某种方式期望使用applicationname生成密钥,但这并没有解决问题.
我发现一些有趣的文档都使用不再编译的代码,我想微软改变了一些东西:
有没有人知道这个问题的解决方案,它也可以在Linux上运行,并且能够在实例之间通过网络共享令牌?
提前致谢!
当用户基于默认的表单身份验证方法登录时,服务器会创建一个包含加密数据的cookie(使用Machine Key作为加密密钥).
这意味着如果有人找到/猜测/访问服务器的机器密钥,他将登录到Web应用程序.
我开发了一些在4台服务器上的应用程序.所以,我为machine.config中的所有服务器硬编码了相同的机器密钥,我无法使用自动生成模式.
asp.net forms-authentication machinekey machine.config formsauthenticationticket
对于IIS托管的ASP.NET MVC 4网站,我想在运行时期间在代码中动态调整机器密钥.
机器密钥,加密和验证密钥以及要使用的算法都存储在数据库中.web.config
我想在应用程序启动期间注入这些值,而不是从文件中读取值,而是让系统使用它们.
有没有办法实现这一点而不必改变web.config
(只改变内存配置)?
我试过访问配置部分,但它被标记为只读并且也是密封的,所以我无法覆盖IsReadOnly()
.但是,setter
对我来说,有一个指示器可能有一种方法可能会删除readonly标志.
var configSection = (MachineKeySection)ConfigurationManager.GetSection("system.web/machineKey");
if (!configSection.IsReadOnly())
{
configSection.ValidationKey = _platformInfo.MachineKey.ValidationKey;
configSection.DecryptionKey = _platformInfo.MachineKey.EncryptionKey;
...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这个目标?我能看到的唯一选择是使用像AppHarbor这样的自定义方法,但是如果可能的话,我宁愿坚持使用内置方法.
如果有人问为什么我想这样做,原因是,这是针对在webfarm中运行的大量相同网站.因此,必须具有非自动生成的密钥(在每个服务器上必须相同).此外,每个网站都应该是隔离的,不应该共享相同的密钥.由于所有网站的物理表示相同,因此它们共享相同的物理位置.这就是web.config文件不能包含特定于应用程序的设置的原因.
编辑:至少确认是否根本不可能,这将是非常有帮助的.如上所述,可以使用自定义验证和加密方法,这些方法将完全避免使用机器密钥设置.谢谢.
我有基于.NET 4.5.1构建的授权服务器并使用Microsoft.Owin.Security.OAuth版本= 3.0.0 http://prntscr.com/hvwhl4 通过machinkey保护的令牌(OAuthAuthorizationServerOptions.AccessTokenFormat是默认值).我还在.NET 4.5.1上有许多应用程序使用者(资源服务器)来验证这些令牌http://prntscr.com/hvwwdu http://prntscr.com/hvwiwr.所有这些应用程序在web.config中都具有相同的machinkey
现在我尝试构建.net core 2.0应用程序,我需要使用来自我的Auth服务器(.net 4.5.1 owin 3.0.0)的相同令牌.如何在.net core 2.0中验证和读取来自Microsoft.Owin.Security.OAuth(3.0.0)令牌的声明?
一个注意事项:我无法更改我的Auth服务器并在Auth服务器中定义DataProtector.所以我需要找到一种方法如何使用现有的机器密钥在.net核心中"解码"OWIN令牌.
更新:所以我在github上打开了问题https://github.com/aspnet/Security/issues/1592
现在它已关闭,答案是:"关闭,因为没有计划支持这一点.您可以使用第三方令牌服务器(如Identity Server)发出可与两个系统一起使用的令牌.或者,您可以为ASP编写自定义代码.NET Core用于处理OWIN/Katana风格的令牌."
我找到了一种解决方案.我在Auth服务器中使用Autofac.Integration.Owin包和OAuthAuthorizationServerMiddleware来定义运行时从哪个资源服务器获取请求,然后定义我需要返回令牌的格式.
我正在尝试在 ASP.Net MVC 应用程序的 Web.Config 中设置机器密钥,但听起来Azure 会自动为每个 Web 应用程序提供唯一的机器密钥并覆盖我的 Web.Config 中的内容。
我想这样做的原因是因为我有一个应用服务女巫用作身份验证应用程序。那是用户登录的地方。而且我还有很多其他应用程序将使用第一个应用程序提供的令牌。这样做将在一个独特的地方对用户进行身份验证,并且用户将能够浏览门户中的某些模块,只需进行一次身份验证。它在 localhost 或托管在 IIS 中运行良好,但在 Azure 托管应用服务上,即使我在 Application_Start 时重置了机器密钥配置部分,它似乎也无法正确读取机器密钥或其他内容。
我尝试了此处描述的解决方案,但正如@gorillapower 所说
似乎这对我们不起作用。我们正在使用 .NET 4.6.1 并使用 OWIN 启动与 app.UseCookieAuthentication() 并使用 Redis 缓存会话提供程序。我实现了上面的,但用户在插槽交换后一直被注销。有任何想法吗?
似乎当您在应用服务计划 (ASP) 的多个实例上运行 ASP.NET 应用程序时,您无需担心 machineKeys,因为应用服务平台将在您的所有实例中使用相同的密钥,因此不需要对您的应用程序进行任何更改。
但就我而言,我们的应用程序都在不同的应用程序服务计划中。所以这个解决方案不适用。
关于这个问题的任何线索?谢谢
我在IIS 7.5中使用.NET 2.0运行时有一个简单的.net应用程序,我在web.config中更改了机器密钥以使用以下内容:
<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps" validation="SHA1"/>
Run Code Online (Sandbox Code Playgroud)
这在本地工作正常,但当我发布到服务器时,我得到一个"HttpException(0x80004005):无法验证数据"每当浏览网站时.我已确保设置编译debug ="false".将验证方法设置为3DES可以消除此问题,但我们需要使用SHA1.我在这里缺少一些配置选项吗?看下面的堆栈跟踪.
[HttpException (0x80004005): Unable to validate data.] System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo, Boolean signData) +1008 System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo) +91 System.Web.UI.Page.EncryptStringWithIV(String s, IVType ivType) +83 System.Web.UI.Page.EncryptString(String s) +30 System.Web.Handlers.RuntimeScriptResourceHandler.GetScriptResourceUrlImpl(List`1 assemblyResourceLists, Boolean zip, Boolean notifyScriptLoaded) +1497 System.Web.Handlers.RuntimeScriptResourceHandler.System.Web.Handlers.IScriptResourceHandler.GetScriptResourceUrl(List`1 assemblyResourceLists, Boolean zip, Boolean notifyScriptLoaded) +1148 System.Web.Handlers.RuntimeScriptResourceHandler.System.Web.Handlers.IScriptResourceHandler.GetScriptResourceUrl(Assembly assembly, String resourceName, CultureInfo culture, Boolean zip, Boolean notifyScriptLoaded) +152 …
我正在尝试运行这个
function hex2a(hex) {
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
//Raw cookie
var cookie = "B417B464CA63FE780584563D2DA4709B03F6195189044C26A29770F3203881DD90B1428139088D945CF6807CA408F201DABBADD59CE1D740F853A894692273F1CA83EC3F26493744E3D25D720374E03393F71E21BE2D96B6110CB7AC12E44447FFBD810D3D57FBACA8DF5249EB503C3DFD255692409F084650EFED205388DD8C08BF7B941E1AC1B3B70B9A8E09118D756BEAFF25834E72357FD40E80E76458091224FAE8";
//decryptionKey from issuers <machineKey>
var deckey = "FFA87B82D4A1BEAA15C06F6434A7EB2251976A838784E134900E6629B9F954B7";
var crypto = require('crypto');
var ivc = cookie, iv, cipherText, ivSize = 16, res = "";
ivc = new Buffer(ivc, 'hex');
iv = new Buffer(ivSize);
cipherText = new Buffer(ivc.length - ivSize);
ivc.copy(iv, 0, 0, ivSize);
ivc.copy(cipherText, 0, ivSize); …
Run Code Online (Sandbox Code Playgroud) 默认情况下,机器密钥设置是自动生成和每个应用程序(AutoGenerate,IsolateApps).MSDN声明解密密钥和验证密钥基于Web应用程序ID.我在我的IIS 7服务器上托管了两个ASP.NET MVC 2站点,但发现机器密钥是相同的.我通过使用反射来验证这一点,以查看ValidationKeyInternal和DecryptionKeyInternal属性.我还通过在一个站点上生成防伪令牌cookie并将其传递给另一个站点来测试它,并且可以读取cookie.
经过反复试验,我发现如果应用程序池标识发生更改,密钥将会更改.这两个站点具有相同的密钥,因为它们在网络服务凭证下运行.一旦我更改了一个站点的应用程序池标识,他们就会开始使用不同的验证/加密密钥.
但是,在将两个站点部署到另一个服务器之后,即使更改了应用程序池标识,我也总是获得相同的机器密钥.这两台服务器具有相同的硬件和软件配置.
我想知道是否存在关于如何在AutoGenerate,IsolateApps设置下生成机器密钥的实际逻辑的参考.在Web上,有很多文章讨论在Web场方案中设置相同的机器密钥.但我在对面遇到了问题.每个Web应用程序自动密钥生成似乎无法正常工作.以前有没有人有同样的问题?
我有两个 .NET Web 应用程序在同一台服务器上运行 - sentinel(托管在https://sentinel.mydomain.com/)和fortknox(在http://www.mydomain.com/fortknox)
Sentinel 是一个身份验证“门户”。FortKnox 是一个“概念证明”应用程序,它使用表单身份验证,但将 loginUrl 设置为https://sentinel.mydomain.com/login(以及一个特殊的 Application_EndRequest 处理程序来限定 ReturnUrl)。Sentinel 是使用 MVC 4 和 Razor 用 .NET 4.0 编写的;FortKnox 是使用 .NET 2.0 的 ASP.NET MVC 2。
我正在使用 ASP.NET FormsAuthentication 并将 cookie 域设置为 ,.mydomain.com
以便设置 的 cookiesentinel.mydomain.com
将与请求一起发送到www.mydomain.com
,反之亦然。cookie 部分运行良好- 两个应用程序都获得相同的 .ASPXAUTH 加密表单票证。
问题是,在我们的生产服务器上,fortknox无法解密由哨兵创建的cookie——即使它们具有相同的机器密钥。即使两个应用程序都在同一个物理盒子上运行,它也不起作用。
用户点击 fortknox,他们被重定向到哨兵,他们登录,设置了 cookie,他们被重定向回 fortknox,然后我得到“无法验证数据”:
Exception: Unable to validate data.
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用MachineKey加密和解密ID。
这是我的调用加密和解密功能的代码:
var encryptedId = Encryption.Protect(profileId.ToString(), UserId);
var decryptedId = Encryption.UnProtect(encryptedId, UserId);
Run Code Online (Sandbox Code Playgroud)
功能如下:
public static string Protect(string text, string purpose)
{
if(string.IsNullOrEmpty(text))
{
return string.Empty;
}
byte[] stream = Encoding.Unicode.GetBytes(text);
byte[] encodedValues = MachineKey.Protect(stream, purpose);
return HttpServerUtility.UrlTokenEncode(encodedValues);
}
public static string UnProtect(string text, string purpose)
{
if(string.IsNullOrEmpty(text))
{
return string.Empty;
}
byte[] stream = HttpServerUtility.UrlTokenDecode(text);
byte[] decodedValues = MachineKey.Unprotect(stream, purpose);
return Encoding.UTF8.GetString(decodedValues);
}
Run Code Online (Sandbox Code Playgroud)
该Protect
方法的输入为15。这将导致EncryptedId变量包含以下字符串:6wOttbtJoVBV7PxhVWXGz4AQVYcuyHvTyJhAoPu4Okd2aKhhCGbKlK_T4q3GgirotfOZYZXke0pMdgwSmC5vxg2
为了对此进行加密,我将此字符串作为参数发送给该UnProtect
方法。解密的结果应为15,但改为:1\05\0
我不明白为什么。我试图在此函数中仅使用整数,但是我仍然遇到相同的问题。解密的输出不同。
machinekey ×10
asp.net ×4
c# ×4
.net-core ×2
asp.net-core ×1
asp.net-mvc ×1
azure ×1
cookies ×1
docker ×1
encryption ×1
iis ×1
linux ×1
node.js ×1
owin ×1
runtime ×1
sha1 ×1
token ×1
web-config ×1