r3plica
r3plica

Reputation: 13367

IdentityServer3 with autofac

I am trying to implement IdentityServer3 into an existing project that uses Autofac. The problem I have come across is that when I set up my custom services, if I run my project and try to authenticate I get this error:

"An error occurred when trying to create a controller of type 'TokenEndpointController'. Make sure that the controller has a parameterless public constructor."

Now I know this is a generic autofac error when a service has not been set up correctly. The error actually moans about my custom UserService stating:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Business.IdentityServer.IdentityServerUserService' can be invoked with the available services and parameters: Cannot resolve parameter 'Business.Providers.IUserProvider userProvider' of constructor 'Void .ctor(Business.Providers.IUserProvider)'.

Now I already had a UserProvider before I started using IdentityServer3 and it was set up in autofac like this:

builder.RegisterType<DatabaseContext>().As<DbContext>().InstancePerDependency();
builder.RegisterType<UserProvider>().As<IUserProvider>().InstancePerDependency();

This was working before, so I know that the UserProvider does actually have all it's dependencies.

My UserService looks like this:

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>());
        }
    }
}

Does anyone know how I can resolve this issue?

Upvotes: 1

Views: 593

Answers (1)

r3plica
r3plica

Reputation: 13367

This was due to how I was configuring the factory. I now have it like this:

    private static IdentityServerServiceFactory Configure(this IdentityServerServiceFactory factory, CormarConfig config)
    {
        var serviceOptions = new EntityFrameworkServiceOptions { ConnectionString = config.SqlConnectionString };
        factory.RegisterOperationalServices(serviceOptions);
        factory.RegisterConfigurationServices(serviceOptions);

        factory.CorsPolicyService = new Registration<ICorsPolicyService>(new DefaultCorsPolicyService { AllowAll = true }); // Allow all domains to access authentication
        factory.Register<DbContext>(new Registration<DbContext>(dr => dr.ResolveFromAutofacOwinLifetimeScope<DbContext>()));
        factory.UserService = new Registration<IUserService>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IUserService>());
        factory.ClientStore = new Registration<IClientStore>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IClientStore>());
        factory.ScopeStore = new Registration<IScopeStore>(dr => dr.ResolveFromAutofacOwinLifetimeScope<IScopeStore>());

        return factory;
    }

My user service is still the same, so everything works.

Upvotes: 1

Related Questions