J'ai joué avec IdentityServer3 dans l'espoir de remplacer notre processus d'authentification actuel. Actuellement, nous utilisons un processus de cadre d'identité personnalisé en utilisant l'infrastructure de première entité de code. J'ai réussi à installer IdentityServer3 et à faire fonctionner les choses "en mémoire". Maintenant, je veux raccorder à notre UserProvider
déjà personnalisé (UserManager
si vous aimez).IdentityServer3, Autofac, IdentityFramework dans le projet existant
Nous utilisons déjà Autofac et avons notre UserProvider
enregistré comme ceci:
builder.RegisterType<UserProvider>().As<IUserProvider>().InstancePerDependency();
J'ai trouvé des documents indiquant que IdentityServer uses Autofac lui-même. Ils recommandent la création d'une usine, puis en utilisant IdentityServerOptions
pour enregistrer le service utilisateur comme ceci:
options.Factory.UserService = new Registration<IUserService>(UserServiceFactory.Create())
Le problème que j'ai avec cela, est le ressemble à l'usine ceci:
public class UserServiceFactory
{
public static AspNetIdentityUserService<User, string> Create()
{
var context = new IdentityDbContext();
var userStore = new UserStore<User>(context);
var userManager = new UserManager<User>(userStore);
return new AspNetIdentityUserService<User, string>(userManager);
}
}
qui utilise le UserManager normal plutôt que notre version personnalisée et il n'utilise pas DI parce que vous créez tout dans la méthode statique. Sûrement, il serait préférable d'utiliser Autofac car nous avons déjà enregistré UserProvider. Donc, je n'ai pas utilisé leur IdentityServerOptions pour appeler la méthode statique. Alors, je l'ai changé mon usine à ceci:
public class IdentityServerUserService : UserServiceBase
{
private readonly IUserProvider _userProvider;
public IdentityServerUserService(IUserProvider userProvider)
{
_userProvider = userProvider;
}
public override async Task AuthenticateLocalAsync(LocalAuthenticationContext context)
{
var user = await _userProvider.FindAsync(context.UserName, context.Password);
if (user != null && !user.Disabled)
{
// Get the UserClaims
// Add the user to our context
context.AuthenticateResult = new AuthenticateResult(user.Id, user.UserName, new List<Claim>());
}
}
}
qui je me suis inscrit dans autofac comme ceci:
builder.RegisterType<IdentityServerUserService>()
.As<IdentityServer3.Core.Services.IUserService>()
.InstancePerDependency();
Et puis j'affecté au IdentityServerOptions.Factory.UserService
comme ceci:
private static void SetupServices(IdentityServerOptions options, ILifetimeScope scope)
{
options.Factory.UserService = new Registration<IUserService>(scope.Resolve<IdentityServerUserService>());
}
Et la portée Je reçois comme ceci:
var config = new HttpConfiguration();
var scope = config.DependencyResolver.GetRootLifetimeScope();
Je crois que cela devrait fonctionner, mais je reçois une erreur lorsque je tente d'utiliser postier pour authentifier:
Autofac.Core.Registration.ComponentNotRegisteredException: Le service demandé « Business.IdentityServerUserService » n'a pas été enregistré. Pour éviter cette exception, enregistrez un composant pour fournir le service, recherchez l'enregistrement du service à l'aide de IsRegistered() ou utilisez la méthode ResolveOptional() pour résoudre une dépendance facultative.
J'ai essayé de changer de InstancePerDependency
à InstancePerLifetimeScope
mais toujours eu la même erreur.
Donc, j'ai quelques questions:
- Est-ce la bonne façon d'attribuer le UserService?
- Est-ce que cela permettra à mes utilisateurs existants de s'authentifier?
- Quelqu'un at-il déjà fait cela? Si oui, l'ont-ils fait fonctionner?
Si quelqu'un peut m'aider avec ces questions, je serais éternellement reconnaissant.