changing package from "Microsoft.Extensions.Configuration.AzureKeyVault" To "Azure.Extensions.AspNetCore.Configuration.Secrets" - asp.net-core-3.1

I am using nuget Microsoft.Extensions.Configuration.AzureKeyVault and I am using below code for asp.net core 3.1 in Program.cs,
I am doing custom certificate authentication for azure keyVault. Also using custom secret management.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
config.AddAzureKeyVault(new AzureKeyVaultConfigurationOptions
{
Vault = "key vault url",
ReloadInterval = TimeSpan.FromSeconds(15),
//authenticate with custom certificate
Client = new KeyVaultClient(CustomCertificateAuthenticationCallback),
Manager = new CustomKeyVaultSecretManager()
});
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
The package Microsoft.Extensions.Configuration.AzureKeyVault is deprecated and I have uninstalled this package and installed the updated one Azure.Extensions.AspNetCore.Configuration.Secrets. After switching to this package I am NOT able to figure our how to use custom validation and how to pass keyvault url

You could try SecretClient method, and refer to this official document about Azure Key Vault Configuration Provider.
using Azure.Security.KeyVault.Secrets;
using Azure.Identity;
using Azure.Extensions.AspNetCore.Configuration.Secrets;
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
if (context.HostingEnvironment.IsProduction())
{
var builtConfig = config.Build();
var secretClient = new SecretClient(new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"),
new DefaultAzureCredential());
config.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
SecretClient doesn't support AuthenticationCallback(Microsoft.Azure.KeyVault.KeyVaultClient.AuthenticationCallback).
If you would like to authenticate with certificate, you could new TokenCredential with Azure.Identity.ClientCertificateCredential.
X509Certificate2 cer = new X509Certificate2(certPath, pfxpassword, X509KeyStorageFlags.EphemeralKeySet);
var secretClient = new SecretClient(new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"),
new ClientCertificateCredential(tenantID, clientID, cer);

As the suggestion in the Accepted Answer does not have the ReloadInterval property, here is the suggestion to keep all properties as in the original code, while using the new package:
using Azure.Security.KeyVault.Secrets;
using Azure.Identity;
using Azure.Extensions.AspNetCore.Configuration.Secrets;
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
if (context.HostingEnvironment.IsProduction())
{
var builtConfig = config.Build();
config.AddAzureKeyVault(
new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"),
new DefaultAzureCredential(),
new AzureKeyVaultConfigurationOptions()
{
Manager = new KeyVaultSecretManager(),
ReloadInterval = TimeSpan.FromSeconds(15)
}
);
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});

Related

WSFederation ADFS login loop .Net Core 2.1

While logging into ADFS(on Premise), I am being redirected after I enter in my credentials and eventually it erros out with the error Exception details: Microsoft.IdentityServer.Web.InvalidRequestException: MSIS7042: The same client browser session has made '6' requests in the last '7' seconds. Contact your administrator for details in Event Viewer. I followed couple of stack overflow suggestion(link) but couldn't resolve the issue. I am running on https and made sure the certificate are right.
Here is my code
namespace TestApp
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
private static string HtmlEncode(string content) =>
string.IsNullOrEmpty(content) ? string.Empty : HtmlEncoder.Default.Encode(content);
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.Secure = CookieSecurePolicy.SameAsRequest;
});
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options =>
{
options.Cookie.Name = ".AspNet.SharedCookie";
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.SameSite = SameSiteMode.None;
})
.AddWsFederation(options =>
{
options.MetadataAddress =
$"https://adfsdomain/FederationMetadata/2007-06/FederationMetadata.xml";
options.Wtrealm = "urn:apptest";
options.Wreply = "https://appdomain/apptest";
options.CallbackPath = "/apptest";
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "https://adfsdomain/adfs/services/trust/"
};
options.SaveTokens = true;
options.RequireHttpsMetadata = false;
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMvc();//.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseCors(policy => policy.SetIsOriginAllowed(origin => origin == "https://adfsdomain"));
app.UseHttpsRedirection();
app.UseStaticFiles();
app.Use(async (context, next) =>
{
if (!context.User.Identity.IsAuthenticated)
{
await context.ChallengeAsync(WsFederationDefaults.AuthenticationScheme);
}
else
{
await next();
}
});
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
I am using .Net Core 2.1 and ADFS 3.0. If I take ASP.NET MVC app and publish it with the same adfs setting my code works like charm, which tells me that the configuration on ADFS has been configured correctly.
Not sure if this can help you guys but I got my ADFS to working with the following:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(options =>
{
options.Wtrealm = this._Configuration["wsfed:realm"];
options.MetadataAddress = string.Format("{0}/federationmetadata/2007-06/federationmetadata.xml", this._Configuration["wsfed:metadata"]);
})
.AddCookie();
You need app.UseAuthorization() before the app.Use(async ...). That's the middleware that takes the headers from the redirect and populates the context.User.

Port sharing using Http.sys in Azure service fabric

Want to host 2 asp .net core 2 websites in Azure service fabric which use port 80. In this link they mentions port sharing but not sure how to configure this? is there a way to mention host name?
Use this class:
public class HttpSysInstanceListener
{
public static ServiceInstanceListener[] CreateListener(Type startupType, string endpointName, string rootPath, int port)
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new HttpSysCommunicationListener(serviceContext, $"{endpointName}", (url, listener) =>
{
return new WebHostBuilder()
.UseHttpSys(options =>
{
options.UrlPrefixes.Add($"http://+:{port}/{rootPath}/");
options.Authentication.Schemes = Microsoft.AspNetCore.Server.HttpSys.AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
options.MaxConnections = null;
})
.ConfigureServices(services => services
.AddSingleton<StatelessServiceContext>(serviceContext)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup(startupType)
.UseUrls(url)
.UseApplicationInsights()
.Build();
}))
};
}
}
If this is a .NET CORE stateless WEB Service API then use HttpSys. However, HttpsSys can be only used with IIS and not KESTREL.
To use HttpSys in a stateless service, override the CreateServiceInstanceListeners method and return a HttpSysCommunicationListener instance:
C#
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
new WebHostBuilder()
.UseHttpSys()
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup<Startup>()
.UseUrls(url)
.Build()))
};
}
also change url to something different than the default:
.UseUrls(url+="WebService")
so for a localhost on port 80 the URL would be:
http(s)//localhost.com/WebService/api/foo
Microsoft Document

Problems with deploying Service Fabric project with Owin to Azure Service Fabric Cluster

I am working on a Service Fabric project with Owin, and I'm having troubles getting it deployed into the cloud. I have searched for others with the same problem, but I only found an answer telling that the error in the cluster tells where in the code it goes wrong. I have followed Microsofts Owin tutorial on how to write the method that fails, but with no luck.
I can run the project on Localhost direcly from Visual Studio, but the problem starts when I deploy it to a Service Fabric cluster in Azure. I have a 5 node cluster running, and when I deploy to it, it starts giving warnings after 2 minutes, and errors after 5 minutes. the status of the application is "inbuild".
Image of warning and Image of error.
I have two services, and the error from my cluster gives the error in these two methods(the same method in each service(OpenAsync)):
public Task<string> OpenAsync(CancellationToken cancellationToken)
{
var serviceEndpoint =
_parameters
.CodePackageActivationContext
.GetEndpoint("ServiceEndpoint");
var port = serviceEndpoint.Port;
var root =
String.IsNullOrWhiteSpace(_appRoot)
? String.Empty
: _appRoot.TrimEnd('/') + '/';
_listeningAddress = String.Format(
CultureInfo.InvariantCulture,
"http://+:{0}/{1}",
port,
root
);
_serverHandle = WebApp.Start(
_listeningAddress,
appBuilder => _startup.Configuration(appBuilder)
);
var publishAddress = _listeningAddress.Replace(
"+",
FabricRuntime.GetNodeContext().IPAddressOrFQDN
);
ServiceEventSource.Current.Message("Listening on {0}", publishAddress);
return Task.FromResult(publishAddress);
}
the error from the cluster tells the error is in this section:
_serverHandle = WebApp.Start(
_listeningAddress,
appBuilder => _startup.Configuration(appBuilder)
);
the other method(from the other service):
public Task<string> OpenAsync(CancellationToken cancellationToken)
{
var serviceEndpoint =
_parameters
.CodePackageActivationContext
.GetEndpoint("ServiceEndpoint");
var port = serviceEndpoint.Port;
var root =
String.IsNullOrWhiteSpace(_appRoot)
? String.Empty
: _appRoot.TrimEnd('/') + '/';
_listeningAddress = String.Format(
CultureInfo.InvariantCulture,
"http://+:{0}/{1}",
port,
root
);
try
{
_serverHandle = WebApp.Start(
_listeningAddress,
appBuilder => _startup.Configuration(appBuilder)
);
}
catch (Exception e)
{
Console.WriteLine(e);
throw e;
}
var publishAddress = _listeningAddress.Replace(
"+",
FabricRuntime.GetNodeContext().IPAddressOrFQDN
);
ServiceEventSource.Current.Message("Listening on {0}", publishAddress);
return Task.FromResult(publishAddress);
}
the error from the cluster tells the error is in this section:
try
{
_serverHandle = WebApp.Start(
_listeningAddress,
appBuilder => _startup.Configuration(appBuilder)
);
}
catch (Exception e)
{
Console.WriteLine(e);
throw e;
}
My StartUp Classes:
public void Configuration(IAppBuilder appBuilder)
{
var corsAttr = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*");
var config = new HttpConfiguration();
config.WithWindsorSetup();
config.WithJsonSetup();
config.MapHttpAttributeRoutes(); //Enable Attribute-routing
config.WithSwaggerSetup();
config.EnsureInitialized();
config.EnableCors(corsAttr);
appBuilder.UseWebApi(config);
}
and where I create a new OwenCommunicationListener:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[] {
new ServiceInstanceListener(initParams => new OwinCommunicationListener("", new Startup.Startup(), initParams))
};
}
I would very much like to be able to deploy it to Azure Service Fabric Cluster without any errors. Have a nice day, and thanks for helping.
you need to write your own custom class that configure the routing and http configuration for Owin listener.
Here is the class which I am using to configure the routing, try with it:
/// <summary>
/// This is the startup class that configure the routing and http configuration for Owin listener.
/// </summary>
public static class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public static void ConfigureApp (IAppBuilder appBuilder)
{
appBuilder.UseCors(CorsOptions.AllowAll);
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
config.Formatters.Remove(config.Formatters.XmlFormatter);
appBuilder.UseWebApi(config);
}
}
pass this class as an action to instance where you are creating instance of OwinCommunication Listener. Here is my code
endpoints.Select(endpoint => new ServiceInstanceListener(
serviceContext => new OwinCommunicationListener(Startup.ConfigureApp, serviceContext,
null, endpoint), endpoint));
This approach is working for me. Try with it hopefully it will work for you too
problem is solved. I edited this code:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return Context.CodePackageActivationContext.GetEndpoints()
.Where(endpoint => endpoint.Protocol.Equals(EndpointProtocol.Http) || endpoint.Protocol.Equals(EndpointProtocol.Https))
.Select(endpoint => new ServiceInstanceListener(serviceContext => new OwinCommunicationListener("", new Startup.Startup(), serviceContext)));
//return new[] {
// new ServiceInstanceListener(initParams => new OwinCommunicationListener("", new Startup.Startup(), initParams))
//};
}

Good algorithm for downloading and caching public signing key for token validation

In a katana web api, I'm using:
appBuilder.UseIdentityServerBearerTokenAuthentication(
new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://...",
ValidationMode = ValidationMode.Local,
RequiredScopes = new[] { "..." },
});
This appears to nicely find the public signing key(s) from the authority and (hopefully?) cache them, etc. Although I haven't tried it, I understand there's an equivalent for ASP.NET Core.
Now I need to do the same thing but not in a web api middleware. So I'm trying to find the code that IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenValidationMiddleware uses to do this. All I can see is that it calls UseOAuthBearerAuthentication, which seems to be in Microsoft.Owin.Security.OAuth. I haven't been able to find a version of that source code that seems to match the signature.
It seems to me that under the covers, somebody is probably using System.IdentityModel.Tokens.JwtSecurityTokenHandler and putting a nice little snippet of code into the IssuerSigningKeyResolver of the TokenValidationParameters. That nice little snippet is getting the signing keys from the metadata address. Anybody know what that code is, or have a piece that works well? Obviously, I could write it but I hate to re-invent the wheel, plus mine would be un-tested.
We are using this class that plugs into the JWT handler:
https://github.com/IdentityServer/IdentityServer3.AccessTokenValidation/blob/master/source/AccessTokenValidation/Plumbing/DiscoveryDocumentIssuerSecurityTokenProvider.cs
Thanks, leastprivilege. Looking deeper at your DiscoverydocumentIssuerSecurityTokenProvider class, I found ConfigurationManager<OpenIdConnectConfiguration>. Using that, I have come up with the following helper class for access token validation outside of OWIN middleware.
Feedback solicited!
using Microsoft.IdentityModel.Protocols;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
namespace WpfClient
{
public class AccessTokenValidator
{
protected TokenValidationParameters _accessTokenValidationParameters;
public AccessTokenValidator(string stsRoot)
{
stsRoot = stsRoot.TrimEnd('/');
var discoveryEndpoint = stsRoot + "/.well-known/openid-configuration";
var webHandler = new WebRequestHandler();
var httpClient = new HttpClient(webHandler);
var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(discoveryEndpoint, httpClient);
_accessTokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = stsRoot,
RequireSignedTokens = true,
ValidateIssuerSigningKey = true,
IssuerSigningKeyResolver = (string token, SecurityToken securityToken, SecurityKeyIdentifier keyIdentifier, TokenValidationParameters validationParameters) => {
var signingTokens = configurationManager.GetConfigurationAsync().Result.JsonWebKeySet.GetSigningTokens();
foreach (var signingToken in signingTokens)
{
foreach (var clause in keyIdentifier)
{
var key = signingToken.ResolveKeyIdentifierClause(clause);
if (key != null)
{
return key;
}
}
}
return null;
},
RequireExpirationTime = true,
ValidateAudience = false, // See https://github.com/IdentityServer/IdentityServer3/issues/1365: "OAuth2 does not use the term 'audience' ... it instead uses the term 'scope' ... 'audience' and the 'aud' claim are JWT specific concepts."
ValidateLifetime = true,
};
}
public void ValidateAccessToken(string accessToken, IEnumerable<string> requiredScopes, IEnumerable<string> requiredRoles)
{
ClaimsPrincipal claimsPrincipal;
SecurityToken securityToken;
var handler = new JwtSecurityTokenHandler();
claimsPrincipal = handler.ValidateToken(accessToken, _accessTokenValidationParameters, out securityToken);
if (claimsPrincipal == null)
{
throw new NullReferenceException("ClaimsPrincipal object returned is null");
}
RequireClaims("scope", requiredScopes, claimsPrincipal);
RequireClaims("role", requiredRoles, claimsPrincipal);
}
private static void RequireClaims(string type, IEnumerable<string> requiredValues, ClaimsPrincipal claimsPrincipal)
{
if (requiredValues != null)
{
var haveClaims = claimsPrincipal.FindAll(type);
var missingRequiredValues = requiredValues.Where(s => !haveClaims.Any(c => c.Value.Equals(s, StringComparison.InvariantCultureIgnoreCase))).ToArray();
if (missingRequiredValues.Any())
{
var list = string.Join(", ", missingRequiredValues);
throw new InvalidDataException($"Missing required {type} claims: {list}");
}
}
}
}
}
I liked the idea of the helper class, but jon-brichoux's implementation still has a lot of code (e.g. iterating over signingTokens) you'd think would be handled by libraries. Microsoft's libraries also have a lot of solid code including refreshing the keys regularly. That implementation looks to be similar to what's recommended by Microsoft at Obtaining SecurityKeys for Validation Dynamically.
A blog post, Manually validating a JWT using .NET, is good but it hits the server and gets the metadata on every validation. Here's what I came up with that seems to work as expected.
You will need to reference the Microsoft.IdentityModel.Protocols.OpenIdConnect and Microsoft.IdentityModel.Protocols NuGet packages.
public class JwtTokenValidator
{
protected static TokenValidationParameters _validationParameters;
public JwtTokenValidator(string metadataAddress, string audience)
{
_validationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = audience,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(metadataAddress, new OpenIdConnectConfigurationRetriever()),
};
}
public void ValidateToken(string token)
{
var jsonWebTokenHandler = new JsonWebTokenHandler();
var tokenValidationResult = jsonWebTokenHandler.ValidateToken(token, _validationParameters);
if (!tokenValidationResult.IsValid)
{
// Handle each exception which tokenValidationResult can contain as appropriate for your service
// Your service might need to respond with a http response instead of an exception.
if (tokenValidationResult.Exception != null)
throw tokenValidationResult.Exception;
throw new InvalidOperationException("invalid token"); // TODO: throw an application-appropriate exception
}
}
}
Usage:
// cache single instance at application initialization
JwtTokenValidator jwtTokenValidator = new JwtTokenValidator($"https:.../.well-known/openid-configuration", "[audience]");
// live check in controller or wherever
jwtTokenValidator.ValidateToken("eyJ0eX...");

Using Autofac with webapi and mvc5.1 not working for webapi

I have a project using both mvc and webapi.
It's a Membership Reboot application so I have taken the example single application project and have slightly modified it to suit.
The DI works ok for controllers however when I try to call a webapi controller I keep getting an error
Make sure that the controller has a parameterless public constructor.
Is there something else I need to do for using autofac with webapi?
This is the code from my startup.cs
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "External",
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive
});
ConfigureMembershipReboot(app);
}
private static void ConfigureMembershipReboot(IAppBuilder app)
{
System.Data.Entity.Database.SetInitializer(new System.Data.Entity.MigrateDatabaseToLatestVersion<DefaultMembershipRebootDatabase, BrockAllen.MembershipReboot.Ef.Migrations.Configuration>());
//System.Data.Entity.Database.SetInitializer(new System.Data.Entity.CreateDatabaseIfNotExists<DefaultMembershipRebootDatabase>());
var cookieOptions = new CookieAuthenticationOptions
{
AuthenticationType = MembershipRebootOwinConstants.AuthenticationType
};
BuildAutofacContainer(app, cookieOptions.AuthenticationType);
app.UseMembershipReboot(cookieOptions);
}
private static void BuildAutofacContainer(IAppBuilder app, string authType)
{
var builder = new ContainerBuilder();
var config = CreateMembershipRebootConfiguration(app);
builder.RegisterInstance(config).As<MembershipRebootConfiguration>();
builder.RegisterType<DefaultUserAccountRepository>()
.As<IUserAccountRepository>()
.As<IUserAccountQuery>()
.InstancePerLifetimeScope();
builder.RegisterType<UserAccountService>().OnActivating(e =>
{
var owin = e.Context.Resolve<IOwinContext>();
var debugging = false;
#if DEBUG
debugging = true;
#endif
e.Instance.ConfigureTwoFactorAuthenticationCookies(owin.Environment, debugging);
})
.AsSelf()
.InstancePerLifetimeScope();
builder.Register(ctx =>
{
var owin = ctx.Resolve<IOwinContext>();
return new OwinAuthenticationService(authType, ctx.Resolve<UserAccountService>(), owin.Environment);
})
.As<AuthenticationService>()
.InstancePerLifetimeScope();
builder.Register(ctx=>HttpContext.Current.GetOwinContext()).As<IOwinContext>();
builder.RegisterControllers(typeof(Startup).Assembly);
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
var container = builder.Build();
System.Web.Mvc.DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
It was a 1 liner :)
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);