gpt4 book ai didi

asp.net-web-api - Autofac、Owin、Webapi 并注入(inject)到 AuthorizationServerProvider

转载 作者:行者123 更新时间:2023-12-01 17:47:01 24 4
gpt4 key购买 nike

阅读有关将 autofac 与 owin 和 webapi 一起使用的问题和文章后,我遇到了一个注入(inject)服务的解决方案,但它不起作用。这是我的代码:

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

var builder = new ContainerBuilder(); // Create the container builder.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); // Register the Web API controllers.

var authcontext = new AuthContext();

builder.RegisterInstance(authcontext).AsSelf().SingleInstance();

//Updated
//var simpleauth = new SimpleAuthorizationServerProvider();
//Updated
// builder.RegisterInstance(simpleauth).SingleInstance().AsSelf().PropertiesAutowired();

builder.Register(x => new UserStore<IdentityUser>(authcontext)).As<IUserStore<IdentityUser>>();

//updated

builder.Register(x =>
{
var p = new SimpleAuthorizationServerProvider();
var userStore = x.Resolve<IUserStore<IdentityUser>>();
p.userManager = new UserManager<IdentityUser>(userStore);
return p;
}).AsSelf().PropertiesAutowired();

builder.RegisterType<AuthRepository>().As<IAuthRepository>().InstancePerRequest().PropertiesAutowired();

var container = builder.Build();

var resolver = new AutofacWebApiDependencyResolver(container); // Create an assign a dependency resolver for Web API to use.
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)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
//updated
Provider = new SimpleAuthorizationServerProvider()
//resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as SimpleAuthorizationServerProvider
};

// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

}


}

但是在SimpleAuthorizationServerProvider类中,当开始调用像ValidateClientAuthentication这样的方法时,所有服务都为空,代码如下:

        public readonly IAuthRepository repository;
public readonly UserManager<IdentityUser> userManager;
public readonly AuthContext dbContext;

public SimpleAuthorizationServerProvider()
{

}

public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;

if (context.TryGetFormCredentials(out clientId, out clientSecret))
{


try
{
Client client = await repository.FindClientById(clientId);
}
}
}

你能帮我一下吗?

已更新

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

            OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = resolver.GetService(typeof(SimpleAuthorizationServerProvider)) as 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.

最佳答案

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

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

  • SimpleAuthorizationServerProvider 中的值是字段而不是属性,所以 PropertiesAutowired对他们不起作用。
  • 这些字段被标记为只读,并且从未设置过。
  • 您有UserManager<IdentityUser>注册为 lambda 但也有 PropertiesAutowired这是行不通的 - 你只能使用 PropertiesAutowired基于反射的组件(例如 RegisterType<T> )。

考虑为您的提供商注册 lambda 并在 lambda 中设置所有内容:

builder.Register(c => {
var p = new SimpleAuthorizationServerProvider();
p.repository = c.Resolve<UserManager<IdentityUser>>();
// ...and so on
return p;
}).AsSelf().SingleInstance();

此外,请记住,如果您注册一个实例(或将某些内容注册为 SingleInstance ,则属性将被解析一次,仅此而已。因此,如果您有一些依赖项 InstancePerDependencyInstancePerRequest ,那就是不会按照你想象的方式工作 - 它们将被解决一次,然后有效地成为单例。

<小时/>

更新1

根据原始和更新的代码,我想到如果您可以查看一些 Autofac 文档以更好地了解其工作原理,那就太好了。例如,使用SimpleAuthorizationServerProvider 中的字段显示您可能不完全了解注入(inject)在 Autofac 中的工作原理或如何正确注册事物以便 Autofac 可以为您完成工作。

例如,查看更新...

  • 您现在已经注册了 SimpleAuthorizationServerProvider 的 lambda但我不明白你在哪里设置了 repository那里有田地。
  • 您不需要 PropertiesAutowired关于SimpleAuthorizationServerProvider注册,因为您正在注册 lambda 并且属性不会 Autowiring (如前所述)。
  • 我认为唯一已注册的组件 InstancePerRequestAuthRepository但是,就像我说的,我看不到在哪里解决或设置 - 这是唯一会生成您注意到的异常的事情。 There is an FAQ on dealing with that exact exception that you should look into.

此外,您还显示了 OAuthServerOptions 的两个不同版本正在初始化,很难判断哪一个是“真实的”。

我建议进行相当大的重构,以使事物能够真正正确地使用 DI。

更改 SimpleAuthorizationServerProvider停止使用公共(public)字段并将它们添加为构造函数参数,以便 Autofac 可以为您连接这些内容。

public class SimpleAuthorizationServerProvider
{
public IAuthRepository Repository { get; private set; }
public UserManager<IdentityUser> UserManager {get; private set; }
public AuthContext Context { get; private set; }
public SimpleAuthorizationServerProvider(
IAuthRepository repository,
UserManager<IdentityUser> userManager,
AuthContext context)
{
this.Repository = repository;
this.UserManager = userManager;
this.AuthContext = context;
}
}

在启动过程中,修复您的注册以删除无关的内容并利用 Autofac Autowiring 的优点。

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

假设这就是所有代码,您应该没问题。如果事情没有设置 - 就像 SimpleAuthorizationServerProvider 之一属性作为 null 出现,或者如果您因为缺少依赖项而收到异常,或者如果您收到有关没有请求范围的异常...那么还有其他事情发生,您没有将其放入您的问题中。

再次,请花时间查看文档并熟悉 Autofac。我认为您遇到的许多问题都是由于对事物连接方式的一些误解而导致的.

关于asp.net-web-api - Autofac、Owin、Webapi 并注入(inject)到 AuthorizationServerProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26612089/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com