依赖注入 – 执行OAuthAuthorizationServerProvider的Autofac依赖注入

前端之家收集整理的这篇文章主要介绍了依赖注入 – 执行OAuthAuthorizationServerProvider的Autofac依赖注入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在创建一个Web Api应用程序,我想使用承载令牌进行用户身份验证.
我实现了令牌逻辑,跟随着 this post,一切似乎都能正常工作.
注意:我没有使用ASP.NET身份提供程序.相反,我已经为它创建了一个自定义用户实体和服务.
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureOAuth(app);

        var config = new HttpConfiguration();
        var container = DependancyConfig.Register();
        var dependencyResolver = new AutofacWebApiDependencyResolver(container);
        config.DependencyResolver = dependencyResolver;

        app.UseAutofacMiddleware(container);
        app.UseAutofacWebApi(config);

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
        var oAuthServerOptions = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,TokenEndpointPath = new PathString("/token"),AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),Provider = new SimpleAuthorizationServerProvider()
        };

        // Token Generation
        app.USEOAuthAuthorizationServer(oAuthServerOptions);
        app.USEOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    }
}

这是我的SimpleAuthorizationServerProvider类的实现

private IUserService _userService;
    public IUserService UserService
    {
        get { return (IUserService)(_userService ?? GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUserService))); }
        set { _userService = value; }
    }

    public async override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin",new[] { "*" });

        var user = await UserService.GetUserByEmailAndPassword(context.UserName,context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant","The user name or password is incorrect.");
            return;
        }

        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        identity.AddClaim(new Claim("sub",context.UserName));
        identity.AddClaim(new Claim("role","user"));

        context.Validated(identity);

    }
}

调用/ token url后,我收到以下错误

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

有没有办法在这个类中使用依赖注入?我正在使用存储库模式来访问我的实体,所以我不认为创建对象上下文的新实例是个好主意.这样做的正确方法是什么?

我也有类似的问题.

这里的问题是,当您尝试在提供程序中注入IUserService时,Autofac检测到它已注册为InstancePerRequest(使用公知的生命周期范围标记“AutofacWebRequest”),但SimpleAuthorizationServerProvider注册在“根”容器范围内其中“AutofacWebRequest”范围不可见.

一个提出的解决方案是将依赖项注册为InstancePerLifetimeScope.这显然解决了这个问题,但是引入了新的问题.所有依赖项都注册在“根”范围内,这意味着对所有请求都具有相同的DbContext和服务实例. Steven在这个answer中解释非常好,为什么不是在请求之间共享DbContext的好主意.

在深入调查任务之后,我已经解决了在OAuthAuthorizationServerProvider类中从OwinContext获取“AutofacWebRequest”的问题,并解决了它的服务依赖关系,而不是让Autofac自动注入它们.为此,我使用了Autofac.Integration.Owin中的OwinContextExtensions.GetAutofacLifetimeScope()扩展方法,请参见下面的示例:

using Autofac.Integration.Owin;
...
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
    ...
    // autofacLifetimeScope is 'AutofacWebRequest'
    var autofacLifetimeScope = OwinContextExtensions.GetAutofacLifetimeScope(context.OwinContext);
    var userService = autofacLifetimeScope.Resolve<IUserService>();
    ...
}

我已经将OAuthAuthorizationServerProvider注册和注入在ConfigureOAuth方法中,类似于another response Laurentiu Stamate提出的与SingleInstance()相关的问题.
我以同样的方式实现了RefreshTokenProvider.

编辑

@BramVandenbussche,这是我在Startup类中的配置方法,您可以在其中看到添加到OWIN管道的中间件的顺序:

public void Configuration(IAppBuilder app)
{
    // Configure Autofac
    var container = ConfigureAutofac(app);

    // Configure CORS
    ConfigureCors(app);

    // Configure Auth
    ConfigureAuth(app,container);

    // Configure Web Api
    ConfigureWebApi(app,container);
}

猜你在找的设计模式相关文章