Asp.net web api Autofac、Owin、Webapi和注入到AuthorizationServerProvider

Asp.net web api Autofac、Owin、Webapi和注入到AuthorizationServerProvider,asp.net-web-api,autofac,owin,Asp.net Web Api,Autofac,Owin,在阅读了有关将autofac与owin和webapi结合使用的问题和文章后,我发现了一个注入服务的解决方案,但它不起作用。这是我的密码: 公共类启动 { 公共无效配置(IAppBuilder应用程序) { HttpConfiguration config=新的HttpConfiguration(); WebApiConfig.Register(配置); var builder=new ContainerBuilder();//创建容器生成器。 builder.RegisterAPI控制器(Ass

在阅读了有关将autofac与owin和webapi结合使用的问题和文章后,我发现了一个注入服务的解决方案,但它不起作用。这是我的密码:

公共类启动
{
公共无效配置(IAppBuilder应用程序)
{
HttpConfiguration config=新的HttpConfiguration();
WebApiConfig.Register(配置);
var builder=new ContainerBuilder();//创建容器生成器。
builder.RegisterAPI控制器(Assembly.getExecutionGassembly());//注册Web API控制器。
var authcontext=new authcontext();
builder.RegisterInstance(authcontext.AsSelf().SingleInstance();
//更新
//var simpleauth=新的SimpleAuthorizationServerProvider();
//更新
//builder.RegisterInstance(simpleauth.SingleInstance().AsSelf().PropertiesAutowired();
Register(x=>newuserstore(authcontext)).As();
//更新
builder.Register(x=>
{
var p=新的SimpleAuthorizationServerProvider();
var userStore=x.Resolve();
p、 userManager=新的userManager(userStore);
返回p;
}).AsSelf().properties自动连线();
builder.RegisterType().As().InstancePerRequest().PropertiesAutowired();
var container=builder.Build();
var resolver=new autofacWebAPI依赖解析程序(容器);//创建一个指定Web API使用的依赖解析程序。
config.dependencyrolver=解析程序;
app.useautofac中间件(容器);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(配置);
配置OAuth(应用程序、解析器);
}
public void ConfigureOAuth(IAppBuilder应用程序、AutoFacWebAPI依赖解析程序解析程序)
{
OAuthAuthorizationServerOptions OAuthServerOptions=新的OAuthAuthorizationServerOptions()
{
AllowInsecureHttp=true,
TokenEndpointPath=新路径字符串(“/token”),
AccessTokenExpireTimeSpan=TimeSpan.FromDays(1),
//更新
Provider=新的SimpleAuthorizationServerProvider()
//作为SimpleAuthorizationServerProvider的resolver.GetService(typeof(SimpleAuthorizationServerProvider))类型
};
//令牌生成
使用OAuthAuthorizationServer(OAuthServerOptions);
使用OAuthBeareAuthentication(新的OAuthBeareAuthenticationOptions());
}
}
但在SimpleAuthorizationServerProvider类中,当调用ValidateClientAuthentication之类的方法时,所有服务都为null,代码如下:

公共只读IAuthRepository存储库;
公共只读用户管理器用户管理器;
公共只读AuthContext dbContext;
公共SimpleAuthorizationServerProvider()
{
}
公共重写异步任务ValidateClientAuthentication(OAuthValidateClientAuthenticationContext)
{
字符串clientId;
字符串clientSecret;
if(context.TryGetFormCredentials(out-clientId,out-clientSecret))
{
尝试
{
Client Client=await repository.FindClientById(clientId);
}
}
}
你能帮我吗

更新

如果在ConfigureOAuth方法中,我使用以下方法:

OAuthAuthorizationServerOptions OAuthServerOptions=new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp=true,
TokenEndpointPath=新路径字符串(“/token”),
AccessTokenExpireTimeSpan=TimeSpan.FromDays(1),
Provider=resolver.GetService(typeof(SimpleAuthorizationServerProvider))作为SimpleAuthorizationServerProvider
};
我得到一个错误:

An exception of type 'Autofac.Core.DependencyResolutionException' occurred in Autofac.dll but was not handled in user code

Additional information: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

注册对象而不是类型的实例时,即使您指定的
属性Autowired
将不会生效,因为Autofac假定您在创建实例时已完成所有需要的工作。如果要将属性连接到中,则需要在激活的处理程序中执行该操作

实际上,在这个示例代码中有很多东西是不起作用的

  • SimpleAuthorizationServerProvider
    中的值是字段而不是属性,因此
    属性自动连线
    对它们不起作用
  • 这些字段被标记为只读,并且从未设置
  • 您已将
    UserManager
    注册为lambda,但还具有无法工作的
    属性autowired
    ——您只能在基于反射的组件(例如,
    RegisterType
    )上使用
    属性autowired
考虑为您的提供商注册lambda,并在lambda中设置所有内容:

builder.Register(c => {
  var p = new SimpleAuthorizationServerProvider();
  p.repository = c.Resolve<UserManager<IdentityUser>>();
  // ...and so on
  return p;
}).AsSelf().SingleInstance();
在启动过程中,修复注册以删除无关内容,并利用Autofac自动布线功能

public class StartUp
{
  public void Configuration(IAppBuilder app)
  {
    var config = new HttpConfiguration();
    WebApiConfig.Register(config);

    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // Register the auth context instance but skip
    // the extra .AsSelf() and .SingleInstance() because
    // it's implicit.
    builder.RegisterInstance(new AuthContext());

    // Use the lambda to resolve the auth context rather
    // than making a closure over an instance.
    builder.Register(c => new UserStore<IdentityUser>(c.Resolve<AuthContext>()))
           .As<IUserStore<IdentityUser>>();

    // Just register the provider type and let Autofac
    // do the work without all this manual stuff. Skip
    // the .AsSelf() because it's implicit if you don't
    // specify other interfaces and don't auto-wire properties
    // because you don't need it.
    builder.RegisterType<SimpleAuthorizationProvider>();

    // This is fine, but I can't tell where it's used - if
    // you are using it at app startup or OUTSIDE a request,
    // you will get that exception you noted. Also, unless
    // you're actually using property injection, lose the
    // .PropertiesAutowired() call.
    builder.RegisterType<AuthRepository>()
           .As<IAuthRepository>()
           .InstancePerRequest()
           .PropertiesAutowired();

    var container = builder.Build();
    var resolver = new AutofacWebApiDependencyResolver(container);
    config.DependencyResolver = resolver;

    app.UseAutofacMiddleware(container);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

    ConfigureOAuth(app, resolver);
  }

  public void ConfigureOAuth(IAppBuilder app, AutofacWebApiDependencyResolver resolver)
  {
    var options = new OAuthAuthorizationServerOptions()
    {
      AllowInsecureHttp = true,
      TokenEndpointPath = new PathString("/token"),
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),

      // If you want the values to be wired up, you have
      // to do a resolve. Note, however, that since you're
      // doing this wire-up at app startup, there's no request
      // scope, so if something in here is registered `InstancePerRequest`
      // you will get an exception.
      Provider =  resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider
    };

    app.UseOAuthAuthorizationServer(options);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
  }
}
公共类启动
{
公共无效配置(IAppBuilder应用程序)
{
var config=新的HttpConfiguration();
WebApiConfig.Register(配置);
var builder=new ContainerBuilder();
RegisterAppController(Assembly.getExecutionGassembly());
//注册auth上下文实例,但跳过
//额外的.AsSelf()和.SingleInstance()是因为
//这是含蓄的。
RegisterInstance(新AuthContext());
//使用lambda解析身份验证上下文,而不是
//而不是对一个实例进行闭包。
builder.Register(c=>newuserstore(c.Resolve()))
.As();
//只需注册提供程序类型并让Autofac
//不用这些手工的东西来做这项工作。跳过
//.AsSelf()是隐式的,因为如果不
//指定其他接口,不自动关联特性
//因为你不需要它。
public class StartUp
{
  public void Configuration(IAppBuilder app)
  {
    var config = new HttpConfiguration();
    WebApiConfig.Register(config);

    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // Register the auth context instance but skip
    // the extra .AsSelf() and .SingleInstance() because
    // it's implicit.
    builder.RegisterInstance(new AuthContext());

    // Use the lambda to resolve the auth context rather
    // than making a closure over an instance.
    builder.Register(c => new UserStore<IdentityUser>(c.Resolve<AuthContext>()))
           .As<IUserStore<IdentityUser>>();

    // Just register the provider type and let Autofac
    // do the work without all this manual stuff. Skip
    // the .AsSelf() because it's implicit if you don't
    // specify other interfaces and don't auto-wire properties
    // because you don't need it.
    builder.RegisterType<SimpleAuthorizationProvider>();

    // This is fine, but I can't tell where it's used - if
    // you are using it at app startup or OUTSIDE a request,
    // you will get that exception you noted. Also, unless
    // you're actually using property injection, lose the
    // .PropertiesAutowired() call.
    builder.RegisterType<AuthRepository>()
           .As<IAuthRepository>()
           .InstancePerRequest()
           .PropertiesAutowired();

    var container = builder.Build();
    var resolver = new AutofacWebApiDependencyResolver(container);
    config.DependencyResolver = resolver;

    app.UseAutofacMiddleware(container);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

    ConfigureOAuth(app, resolver);
  }

  public void ConfigureOAuth(IAppBuilder app, AutofacWebApiDependencyResolver resolver)
  {
    var options = new OAuthAuthorizationServerOptions()
    {
      AllowInsecureHttp = true,
      TokenEndpointPath = new PathString("/token"),
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),

      // If you want the values to be wired up, you have
      // to do a resolve. Note, however, that since you're
      // doing this wire-up at app startup, there's no request
      // scope, so if something in here is registered `InstancePerRequest`
      // you will get an exception.
      Provider =  resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider
    };

    app.UseOAuthAuthorizationServer(options);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
  }
}