I'm having a hard time getting this to work. Currently I already have got an IdentityServer4, an Angular2SPA and a WebAPI 2.2 for ODATA running. All services are running in individual projects on asp.net core.
- IdentityServer4
- Angular2SPA
- WebAPI2.2 .core targeting .Net462
The WebAPI runs fine as long as i dont try to connect it to the IdentityServer. I have verified that my setup, beside the WebAPI, works correctly. I have also tested the WebAPI connection configuration with the IdentityServer3.Samples on Github by connecting their WebAPISample with my IdentityServer.
WebAPI
Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//services.AddAuthorization();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(LogLevel.Debug);
loggerFactory.AddDebug();
app.UseOwinApp(owinApp =>
{
if (env.IsDevelopment())
{
owinApp.UseErrorPage(new ErrorPageOptions()
{
ShowCookies = true,
ShowEnvironment = true,
ShowExceptionDetails = true,
ShowHeaders = true,
ShowQuery = true,
ShowSourceCode = true
});
}
owinApp.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
HttpConfiguration config = new HttpConfiguration();
JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();
owinApp.UseCookieAuthentication(new CookieAuthenticationOptions());
owinApp.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://authentication.bl.at:5000",
RequiredScopes = new[] { "bl.API" },
//ValidationMode = ValidationMode.ValidationEndpoint,
//DelayLoadMetadata = true,
//// client credentials for the introspection endpoint
ClientId = "bl.API",
ClientSecret = "secret"
});
WebAPIConfig.Register(config);
ODataModelBuilder odataMetadataBuilder = new ODataConventionModelBuilder();
odataMetadataBuilder.EntitySet<Product>("Products");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: odataMetadataBuilder.GetEdmModel());
owinApp.UseWebApi(config);
});
}
}
OwinExtensions.cs
public static class OwinExtensions
{
public static IApplicationBuilder UseOwinApp(this IApplicationBuilder aspNetCoreApp, Action<IAppBuilder> configuration)
{
return aspNetCoreApp.UseOwin(setup => setup(next =>
{
AppBuilder owinAppBuilder = new AppBuilder();
IApplicationLifetime aspNetCoreLifetime = (IApplicationLifetime)aspNetCoreApp.ApplicationServices.GetService(typeof(IApplicationLifetime));
AppProperties owinAppProperties = new AppProperties(owinAppBuilder.Properties);
owinAppProperties.OnAppDisposing = aspNetCoreLifetime?.ApplicationStopping ?? CancellationToken.None;
owinAppProperties.DefaultApp = next;
configuration(owinAppBuilder);
return owinAppBuilder.Build<Func<IDictionary<string, object>, Task>>();
}));
}
}
WebAPIConfig.cs
public class WebAPIConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}
Exceptions
The WebAPI works as expected as long as oauth is disabled, when it's enabled it throws the following exception on startup:
Unbehandelte Ausnahme: System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei IdentityServer3.AccessTokenValidation.DiscoveryDocumentIssuerSecurityTokenProvider..ctor(String discoveryEndpoint, IdentityServerBearerTokenAuthenticationOptions options, ILoggerFactory loggerFactory)
bei Owin.IdentityServerBearerTokenValidationAppBuilderExtensions.<>c__DisplayClass9.<ConfigureLocalValidation>b__8()
bei System.Lazy`1.CreateValue()
bei System.Lazy`1.LazyInitValue()
bei Owin.IdentityServerBearerTokenValidationAppBuilderExtensions.UseIdentityServerBearerTokenAuthentication(IAppBuilder app, IdentityServerBearerTokenAuthenticationOptions options)
bei WebAPI.Startup.<>c__DisplayClass1_0.<Configure>b__0(IAppBuilder owinApp) in C:\Users\User\Documents\visual studio 2015\Projects\TestProject\src\WebAPI\Startup.cs:Zeile 78.
bei WebAPI.Config.OwinExtensions.<>c__DisplayClass0_0.<UseOwinApp>b__1(Func`2 next) in C:\Users\User\Documents\visual studio 2015\Projects\TestProject\src\WebAPI\Config\OwinExtensions.cs:Zeile 29.
bei Microsoft.AspNetCore.Builder.OwinExtensions.<>c__DisplayClass0_1.<UseOwin>b__1(RequestDelegate next1)
bei Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build()
bei Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
bei Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
bei WebAPI.Program.Main(String[] args) in C:\Users\User\Documents\visual studio 2015\Projects\TestProject\src\WebAPI\Program.cs:Zeile 21.
I have also tried enabling delayLoadMetadata but this throws the following exception:
Unbehandelte Ausnahme: System.Reflection.TargetInvocationException: Ein Aufrufziel hat einen Ausnahmefehler verursacht. ---> System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenValidationMiddleware..ctor(Func`2 next, IAppBuilder app, IdentityServerOAuthBearerAuthenticationOptions options, ILoggerFactory loggerFactory)
bei lambda_method(Closure , Func`2 , IAppBuilder , IdentityServerOAuthBearerAuthenticationOptions , ILoggerFactory )
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
bei System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
bei System.Delegate.DynamicInvokeImpl(Object[] args)
bei Microsoft.Owin.Builder.AppBuilder.BuildInternal(Type signature)
bei Microsoft.Owin.Builder.AppBuilderExtensions.Build[TApp](IAppBuilder builder)
bei WebAPI.Config.OwinExtensions.<>c__DisplayClass0_0.<UseOwinApp>b__1(Func`2 next) in C:\Users\User\Documents\visual studio 2015\Projects\TestProject\src\WebAPI\Config\OwinExtensions.cs:Zeile 31.
bei Microsoft.AspNetCore.Builder.OwinExtensions.<>c__DisplayClass0_1.<UseOwin>b__1(RequestDelegate next1)
bei Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build()
bei Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
bei Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
bei WebAPI.Program.Main(String[] args) in C:\Users\User\Documents\visual studio 2015\Projects\TestProject\src\WebAPI\Program.cs:Zeile 21.
I think this issue might be related to .Core/Owin dependency injection of ILoggerFactory. Might be a lifespan issue between these two?