MVC6:EF7类的依赖注入

时间:2016-01-30 02:48:33

标签: asp.net-mvc entity-framework

我正在尝试使用DI将一个加密/解密类的实例注入ApplicationUser,这是一个用于在MVC6应用程序中保存用户信息的类。但是我错过了一些东西,因为它不起作用。

ApplicationUser类如下所示:

public class ApplicationUser : IdentityUser
{
    [FromServices]
    [NotMapped]
    public StringCrypt Crypt { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string SiteID { get; set; }

    [NotMapped]
    public string SitePassword {
        get
        {
            bool requiresMigration = false;
            bool wasRevoked = false;

            return Crypt.Unprotect(SitePW, out requiresMigration, out wasRevoked);
        }

        set { SitePW = Crypt.Protect(value); }
    }

    protected string SitePW { get; set; }
}

这是为了支持第三方网站的密码以加密形式存储在数据库中,但可以解密形式透明地访问的情况。

StringCrypt类依赖于内置的ASPNET6数据保护API:

public class StringCrypt : IStringCrypt
{
    private IPersistedDataProtector _dp;

    public StringCrypt( IDataProtectionProvider dpProvider )
    {
        _dp = (IPersistedDataProtector) dpProvider.CreateProtector("passwords");
    }

    public string Unprotect( string protectedData, out bool requiresMigration, out bool wasRevoked )
    {
        bool ignoreRevocation = true;

        byte[] protectedBytes = Convert.FromBase64String(protectedData);
        byte[] unprotectedBytes = _dp.DangerousUnprotect(protectedBytes, ignoreRevocation, out requiresMigration, out wasRevoked);

        return Encoding.UTF8.GetString(unprotectedBytes);
    }

    public string Protect( string clearText )
    {
        byte[] clearBytes = Encoding.UTF8.GetBytes(clearText);
        byte[] protectedBytes = _dp.Protect(clearBytes);

        string result = Convert.ToBase64String(protectedBytes);

        return result;
    }
}

我尝试将这一切与内置的依赖注入系统结合在一起,需要对startup.cs中的ConfigureServices方法进行一些调整:

    public void ConfigureServices( IServiceCollection services )
    {
        // normal stuff created by VS2015...

        services.AddDataProtection();

        // have to avoid setting a file path when we're invoked by dnx
        // HostEnvironment is an instance of IHostingEnvironment, set in
        // the constructor for Startup
        if( (HostEnvironment != null) && (HostEnvironment.WebRootPath != null ) )
            services.ConfigureDataProtection(configure =>
            {
                string pathToCryptoKeys = Path.Combine(HostEnvironment.WebRootPath, "dp_keys");
                configure.PersistKeysToFileSystem(new DirectoryInfo(pathToCryptoKeys));
                configure.SetDefaultKeyLifetime(TimeSpan.MaxValue);
            });

        services.AddTransient<StringCrypt>();
    }

但是当我运行该站点,并且我在ApplicationUser中进行Crypt.Protect()调用时,它会失败,因为Crypt属性(应该是StringCrypt的一个实例)是未定义的。这意味着它从未被设置......这就是我认为用[FromServices]标记它的方式。

是否以某种方式创建了ApplicationUser的实例来绕过DI系统?或者[FromServices]不能在控制器或视图之外工作?

0 个答案:

没有答案