0

我很难让这个工作。目前我已经有一个 IdentityServer4、一个 Angular2SPA 和一个用于 ODATA 运行的 WebAPI 2.2。所有服务都在 asp.net core 上的单个项目中运行。

  • 身份服务器4
  • Angular2SPA
  • WebAPI2.2 .core 针对.Net462

只要我不尝试将 WebAPI 连接到 IdentityServer,它就可以正常运行。我已经验证了我的设置,除了 WebAPI,可以正常工作。我还通过将 WebAPISample 与我的 IdentityServer 连接,在 Github 上使用 IdentityServer3.Samples 测试了 WebAPI 连接配置。

网络API

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

例外

只要禁用 oauth,WebAPI 就会按预期工作,启用后它会在启动时引发以下异常:

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.

我也尝试过启用 delayLoadMetadata 但这会引发以下异常:

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.

我认为这个问题可能与 ILoggerFactory 的 .Core/Owin 依赖注入有关。可能是这两者之间的寿命问题?

4

2 回答 2

0

我遇到了同样的问题,我也尝试使用 DelayLoadMetadata = true选项,但没有任何成功。

为了解决这个问题,我需要在调用 app.UseIdentityServerBearerTokenAuthentication(GetOptions()); 之前使用 app.SetLoggerFactory 设置默认记录器;为此,您可能需要投放广告

using Microsoft.Owin.Logging;

到您的使用并可能添加程序集引用,这会将SetLoggerFactory方法添加到应用程序对象。(这是一个扩展)。就我而言,我只是使用这样的默认记录器完成了它:

app.SetLoggerFactory(Microsoft.Owin.Logging.LoggerFactory.Default);
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
    {
    //some stuff
    });
);
于 2017-06-21T07:32:45.893 回答
0

您在启用之前和之后遇到的异常DelayLoadMetadata是不同的,一个来自构造函数,DiscoveryDocumentIssuerSecurityTokenProvider而另一个来自构造函数IdentityServerBearerTokenValidationMiddleware

如果您查看UseIdentityServerBearerTokenAuthentication的实现,您会看到两个模块都依赖于从该行loggerFactory获取的模块IApplicationBuilder

        var loggerFactory = app.GetLoggerFactory();

我不是 .net 核心专家,但你使用UseOwin扩展方法的方式对我来说有点奇怪,你AppBuilder的 owin 管道中有一个新实例,而不是使用现有的 - aspNetCoreApp,我猜是没有记录器工厂注册了 的新实例AppBuilder,因此当 IdentityServer3 的模块中需要它时,它会object is null异常爆炸。

您可以通过在调用之前设置断点轻松找到 并在调试窗口中IdentityServerBearerTokenValidationMiddleware手动执行以查看它是否返回任何内容owinAppBuilder.GetLoggerFactory()Immediate

于 2017-04-05T20:42:35.623 回答