.NET身份令牌无效,机器密钥相同 [英] .NET Identity Token invalid, machine key the same

查看:65
本文介绍了.NET身份令牌无效,机器密钥相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个问题,我生成了令牌以放入电子邮件中,以供用户重设密码.我正在负载平衡器后面的两个Web服务器上的IIS 7上运行.net 4.5站点.

I am having a problem where I generate a token to put in an email for a user to reset their password. I am running .net 4.5 sites on IIS 7 on two web servers behind a load balancer.

只要令牌在从其生成的同一服务器上使用,令牌就可以很好地工作.但是,如果另一台服务器受到攻击,则为无效令牌".错误生成.

The token works great as long as it is used on the same server it was generated from. But if the other server is the one that gets hit, then an "Invalid token." error is generated.

我有三个可以测试的网址.负载均衡的URL,并且URL直接到达负载均衡器后面的每个服务器.我可以从负载平衡的URL生成令牌,并验证我命中的服务器,然后可以在同一服务器的直接URL上使用该令牌.但是在相反的服务器上使用它的组合都无效.

I have three urls I can test from. The load balanced url, and urls directly to each server behind the load balancer. I can generate a token from the load balanced url and verify which server I hit, then I can use that token on the direct url for the same server. But no combination of using it on the opposing server works.

最初,我的机器密钥在两台计算机上都不相同,我在一个多月前解决了该问题.但这并没有解决问题.两台服务器都使用相同的代码库.而且,负载均衡域名令牌适用于直接通向其后方服务器的域名,这意味着域名本身并不是我所知的一个重要因素.

Initially my machine key was not the same on both machines, and I fixed that issue over a month ago. But it has not solved the issue. Both servers are using the same code base. And the fact that the load balanced domain name token works on the domain name that goes directly to the server behind it means that the domain name itself is not a factor as near as I can tell.

我的配置还有什么问题?

What else could be wrong with my configuration?

推荐答案

事实证明,.net Identity系统默认情况下无法使用其UserTokenProvider处理Web场.到目前为止,我发现此问题的唯一方法是编写自己的UserTokenProvider.幸运的是,事实证明这很容易做到,并且只需要很少的代码.

It turns out that the .net Identity system cannot handle web farms by default using it's UserTokenProvider. So far the only way I have found around this issue is to write your own UserTokenProvider. Fortunately, it turns out this is very easy to do and requires very little code.

您可能已经有一个类似于以下内容的UserManager实现:

You probably already have a UserManager implementation that looks similar to this:

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager() : base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
    {
        var provider = new DpapiDataProtectionProvider("MyApp");
        this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create(".Net Identity"));
    }

}

将其更改为这样.

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager() : base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
    {
        var provider = new MachineKeyProtectionProvider();
        this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create(".Net Identity"))
        {
            TokenLifespan = TimeSpan.FromHours(24)
        };
    }

}

然后创建缺少的类:

/// <summary>
/// Wrapper for the custom @MachineKeyDataProtector class
/// </summary>
public class MachineKeyProtectionProvider : IDataProtectionProvider
{
    public IDataProtector Create(params string[] purposes)
    {
        return new MachineKeyDataProtector(purposes);
    }
}

/// <summary>
/// Custom key provider because Microsoft's default provider does not support web farms
/// </summary>
public class MachineKeyDataProtector : IDataProtector
{
    private readonly string[] _purposes;

    public MachineKeyDataProtector(string[] purposes)
    {
        _purposes = purposes;
    }

    public byte[] Protect(byte[] userData)
    {
        return MachineKey.Protect(userData, _purposes);
    }

    public byte[] Unprotect(byte[] protectedData)
    {
        return MachineKey.Unprotect(protectedData, _purposes);
    }
}

这篇关于.NET身份令牌无效,机器密钥相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆