如何在Startup类中使用或解决服务(或依赖项)

时间:2019-08-05 21:05:28

标签: c# .net owin autofac

使用IdentityServerBearerTokenAuthentication中间件时,我想访问在WebApi配置中注册的服务。具体来说,我想调用一个服务来给我默认的用户ID,并将其添加到请求中的Claims中。在下面的TODO lambda示例代码中查看我的OnValidateIdentity

//startup.cs
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = ConfigurationManager.AppSettings["Federation.IdentityServerPath"]
            });

            // azure functions will authenticate using Azure AD Tokens
            app.UseWindowsAzureActiveDirectoryBearerAuthentication(
                new WindowsAzureActiveDirectoryBearerAuthenticationOptions
                {
                    Audience = ConfigurationManager.AppSettings["ida:Audience"],
                    Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                    Provider = new OAuthBearerAuthenticationProvider()
                    {
                        OnValidateIdentity = context =>
                        {

                            //add the account id claim if it's specified in the header
                            var accountIdString = context.Request.Headers["X-AccountId"];
                            if (!string.IsNullOrWhiteSpace(accountIdString) && Guid.TryParse(accountIdString, out var _))
                            {
                                context.Ticket.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, accountIdString));
                            }
                            else
                            {
                                //TODO: Need to pull the system user or admin user and jam that account id into NameIdentifier.
                                var systemDefaultId = "";
                                // How do I get a dependency from HttpContext or context.OwinContext?????
                                context.Ticket.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, systemDefaultId));
                            }

                            context.Ticket.Identity.AddClaim(new Claim("cl_aad_user", "true"));

                            return Task.FromResult<object>(null);
                        }
                    }
                }
            );
        }
    }
}

应用程序服务已使用autofac构建器模式注册。 例如 builder.RegisterType<AccountInfoService>().As<IAccountInfoService>().InstancePerRequest();在Global类(Global.asax)中调用的静态方法中。

// Global.asax.cs
...
private void Application_Start(object sender, EventArgs e)
        {
            // ... truncated code               
            // registers the services 
            GlobalConfiguration.Configure(WebApiConfig.Register);
        }

我曾尝试从HttpContext获取服务,但是它始终解析为null。 (即var db = (IOutcomesContext)HttpContext.Current.Request.RequestContext.HttpContext.GetService(typeof(IAccountService));) 我还检查了this answer,但我没有使用该中间件。

这是我注册依赖项的方式。

  // WebApiConfig.cs
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            RegisterIoc(config);
        }

        private static void RegisterIoc(HttpConfiguration config)
        {
            ContainerBuilder builder = GetIocContainerBuilder();
            builder.RegisterWebApiFilterProvider(config);

            //all the external dependencies
            builder.RegisterType<InstitutionRequestContext>().As<IInstitutionRequestContext>().InstancePerRequest();

            Autofac.IContainer container = builder.Build();
            GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        }

        internal static ContainerBuilder GetIocContainerBuilder()
        {
            ContainerBuilder builder = new ContainerBuilder();

            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

            // ... truncated service list
            builder.RegisterType<AccountInfoService>().As<IAccountInfoService>().InstancePerRequest();

            return builder;
        }

    }

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我最终通过按this answer中所述切换应用程序以使用app.UseAutofacMiddleware(container);中间件来解决了上述问题。

对于我的特定用例,它仅涉及一些更改,特别是...

  1. 从“全局”配置文件(例如Global.asax)中删除自动文件
  2. 更新我的WebApiConfig以返回Autofac.IContainer
  3. 按照their documentation
  4. 中所述,向Startup.Configure类添加3个左右的方法调用