Register ISecureDataFormat<AuthenticationTicket> using Autofac
如何使用 autofac 注册
我尝试用这种方式注册:
1 2 3 | builder.RegisterType<SecureDataFormat<AuthenticationTicket>>() .As<ISecureDataFormat<AuthenticationTicket>>() .InstancePerLifetimeScope(); |
但我得到了错误:
An error occurred when trying to create a controller of type 'AccountController'. Make sure that the controller has a parameterless public constructor.
....InnerException":{"Message":"An error has occurred.","ExceptionMessage":"None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Microsoft.Owin.Security.DataHandler.SecureDataFormat`1[Microsoft.Owin.Security.AuthenticationTicket]' can be invoked with the available services and parameters
AccountController.cs
1 2 3 4 5 6 7 8 | public AccountController(ApplicationUserManager _userManager, IAuthenticationManager authenticationManager, ISecureDataFormat<AuthenticationTicket> accessTokenFormat) { this._userManager = _userManager; this._authenticationManager = authenticationManager; this._accessTokenFormat = accessTokenFormat; } |
在构造函数中没有
安全数据格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #region Assembly Microsoft.Owin.Security, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 #endregion using Microsoft.Owin.Security.DataHandler.Encoder; using Microsoft.Owin.Security.DataHandler.Serializer; using Microsoft.Owin.Security.DataProtection; namespace Microsoft.Owin.Security.DataHandler { public class SecureDataFormat<TData> : ISecureDataFormat<TData> { public SecureDataFormat(IDataSerializer<TData> serializer, IDataProtector protector, ITextEncoder encoder); public string Protect(TData data); public TData Unprotect(string protectedText); } } |
身份验证票
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #region Assembly Microsoft.Owin.Security, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 #endregion using System.Security.Claims; namespace Microsoft.Owin.Security { public class AuthenticationTicket { public AuthenticationTicket(ClaimsIdentity identity, AuthenticationProperties properties); public ClaimsIdentity Identity { get; } public AuthenticationProperties Properties { get; } } } |
我想跟进@Cyril 的回答。我们有一个服务器场,它使用机器密钥来保护数据,所以我们的注册,在经历了很多挫折之后,看起来像这样:(我们使用 Autofac 进行注册,所以在这方面它可能看起来有点不同)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | builder.RegisterType<Base64UrlTextEncoder>().As<ITextEncoder>().InstancePerLifetimeScope(); builder.RegisterType<TicketSerializer>() .As<IDataSerializer<AuthenticationTicket>>() .InstancePerLifetimeScope(); builder.Register(c => new MachineKeyDataProtectionProvider().Create( typeof(OAuthAuthorizationServerMiddleware).Namespace, "Access_Token", "v1")) .As<IDataProtector>() .InstancePerLifetimeScope(); builder.RegisterType<SecureDataFormat<AuthenticationTicket>>() .As<ISecureDataFormat<AuthenticationTicket>>() .InstancePerLifetimeScope(); |
的简单package器
1 2 3 4 5 6 7 8 9 10 11 12 13 | public virtual MachineKeyDataProtector Create(params string[] purposes) { return new MachineKeyDataProtector(purposes); } public virtual DataProtectionProviderDelegate ToOwinFunction() { return purposes => { MachineKeyDataProtector dataProtecter = Create(purposes); return new DataProtectionTuple(dataProtecter.Protect, dataProtecter.Unprotect); }; } |
然后,随后,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | internal class MachineKeyDataProtector : IDataProtector { private readonly string[] _purposes; public MachineKeyDataProtector(params string[] purposes) { _purposes = purposes; } public virtual byte[] Protect(byte[] userData) { return MachineKey.Protect(userData, _purposes); } public virtual byte[] Unprotect(byte[] protectedData) { return MachineKey.Unprotect(protectedData, _purposes); } } |
错误消息说明 Autofac 无法创建
您似乎没有为
1 2 3 4 5 | builder.RegisterType<ITextEncoder, Base64UrlTextEncoder>(); builder.RegisterType<TicketSerializer>() .As<IDataSerializer<AuthenticationTicket>>(); builder.Register(c => new DpapiDataProtectionProvider().Create("ASP.NET Identity")) .As<IDataProtector>(); |