尝试全局启用CORS时出现异常

时间:2016-09-01 07:24:41

标签: c# asp.net cors asp.net-core asp.net-core-mvc

我正试图在全球范围内启用CORS:

services.Configure<MvcOptions>(options =>
{
    options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
});

当我尝试加载我的应用程序时,我收到此异常:

InvalidOperationException:没有类型的服务&#39; Microsoft.AspNetCore.Mvc.Cors.CorsAuthorizationFilter&#39;已经注册。

这些是Startup.cs和project.json:

using System;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Mvc.Server.Models;
using Mvc.Server.Services;
using NWebsec.AspNetCore.Middleware;
using System.IO;
using Newtonsoft.Json.Serialization;
using Swashbuckle.Swagger.Model;
using System.Globalization;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.Options;
using Mvc.Server.Configuration;
using IdentityServer4.Contrib.AspNetIdentity;
using Mvc.Server.Extensions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Cors.Internal;

namespace Mvc.Server
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("config.json")
                .AddEnvironmentVariables()
                .Build();

            services.AddLocalization(options => options.ResourcesPath = "Resources");

            services
                .AddMvcCore()
                .AddJsonFormatters()
                .AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
                .AddDataAnnotationsLocalization()
                .AddAuthorization();


            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseNpgsql(configuration["Data:DefaultConnection:ConnectionString"]));


            services.AddTransient<IEmailSender, AuthMessageSender>();
            services.AddTransient<ISmsSender, AuthMessageSender>();

            // Configure supported cultures and localization options
            services.Configure<RequestLocalizationOptions>(options =>
            {
                var supportedCultures = new[]
                {
                    new CultureInfo("en"),
                    new CultureInfo("bg")
                };

                // State what the default culture for your application is. This will be used if no specific culture
                // can be determined for a given request.
                options.DefaultRequestCulture = new RequestCulture(culture: "en", uiCulture: "en");

                // You must explicitly state which cultures your application supports.
                // These are the cultures the app supports for formatting numbers, dates, etc.
                options.SupportedCultures = supportedCultures;

                // These are the cultures the app supports for UI strings, i.e. we have localized resources for.
                options.SupportedUICultures = supportedCultures;

                // You can change which providers are configured to determine the culture for requests, or even add a custom
                // provider with your own logic. The providers will be asked in order to provide a culture for each request,
                // and the first to provide a non-null result that is in the configured supported cultures list will be used.
                // By default, the following built-in providers are configured:
                // - QueryStringRequestCultureProvider, sets culture via "culture" and "ui-culture" query string values, useful for testing
                // - CookieRequestCultureProvider, sets culture via "ASPNET_CULTURE" cookie
                // - AcceptLanguageHeaderRequestCultureProvider, sets culture via the "Accept-Language" request header
                //options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
                //{
                //  // My custom request culture logic
                //  return new ProviderCultureResult("en");
                //}));
            });

            services.AddCors(options =>
            {
                options.AddPolicy("AllowSpecificOrigin",
                     builder => builder.WithOrigins("http://localhost:18509").AllowAnyHeader().AllowAnyMethod().AllowCredentials());
            });

            services.Configure<MvcOptions>(options =>
            {
                options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
            });

            // Register the Identity services.
            services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()
                .AddEntityFrameworkStores<ApplicationDbContext, Guid>()
                .AddDefaultTokenProviders();

            services.AddIdentityServer(options =>
            {
                //options.SigningCertificate = cert;
                // Not implemented yet in IdentityServer4
                options.Endpoints.EnableEndSessionEndpoint = false;
            })
                   .AddInMemoryClients(Clients.Get())
                   .AddInMemoryScopes(Scopes.Get())
                   .ConfigureAspNetIdentity<ApplicationUser>()
                   .AddCustomGrantValidator<CustomGrantValidator>()
                   .SetTemporarySigningCredential();

        }

        public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory)
        {
            app.UseCors("AllowSpecificOrigin");

            var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
            app.UseRequestLocalization(locOptions.Value);


            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            // Add a middleware used to validate access
            // tokens and protect the API endpoints.
            app.UseOAuthValidation();

            app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions()
            {
                ClientId = "registration",
                RequireHttpsMetadata = false,
                Authority = "http://localhost:54540/",

            });

            // Alternatively, you can also use the introspection middleware.
            // Using it is recommended if your resource server is in a
            // different application/separated from the authorization server.
            // 
            // app.UseOAuthIntrospection(options => {
            //     options.AutomaticAuthenticate = true;
            //     options.AutomaticChallenge = true;
            //     options.Authority = "http://localhost:54540/";
            //     options.Audience = "resource_server";
            //     options.ClientId = "resource_server";
            //     options.ClientSecret = "875sqd4s5d748z78z7ds1ff8zz8814ff88ed8ea4z4zzd";
            // });

            //app.UseCsp(options => options.DefaultSources(directive => directive.Self())
            //    .ImageSources(directive => directive.Self()
            //        .CustomSources("*"))
            //    .ScriptSources(directive => directive.Self()
            //        .UnsafeInline())
            //    .StyleSources(directive => directive.Self()
            //        .UnsafeInline()));

            app.UseXContentTypeOptions();

            app.UseXfo(options => options.Deny());

            app.UseXXssProtection(options => options.EnabledWithBlockMode());

            app.UseIdentity();
            app.UseIdentityServer();

            var googleOptions = new GoogleOptions
            {
                //ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com",
                ClientId = "713128117807-iu95ps09o6aegvjhmngql4rbiklg2bt2.apps.googleusercontent.com",
                //ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f",
                ClientSecret = "6ZRzzsTH9tK69WaenScZwwS9",
                Scope = { "email",
                    "openid",
                    "profile",
                    "https://www.googleapis.com/auth/userinfo.profile",
                    "https://www.googleapis.com/auth/plus.me",
                    "https://www.googleapis.com/auth/plus.login",
                    "https://www.googleapis.com/auth/contacts.readonly",
                    "https://www.googleapis.com/auth/contacts",
                    "https://www.googleapis.com/auth/plus.login",
                    "https://www.googleapis.com/auth/user.addresses.read",
                    "https://www.googleapis.com/auth/user.birthday.read",
                    "https://www.googleapis.com/auth/user.emails.read",
                    "https://www.googleapis.com/auth/user.phonenumbers.read",
                    "https://www.googleapis.com/auth/userinfo.email",
                    "https://www.googleapis.com/auth/plus.login",
                },
                SaveTokens = true,
                AccessType = "offline"
            };

            //googleOptions.Scope.Add("email");
            //googleOptions.Scope.Add("https://www.googleapis.com/auth/contacts");
            //googleOptions.Scope.Add("https://www.googleapis.com/auth/contacts.readonly");
            //googleOptions.Scope.Add("https://www.googleapis.com/auth/user.addresses.read");
            //googleOptions.Scope.Add("https://www.googleapis.com/auth/user.birthday.read");
            //googleOptions.Scope.Add("https://www.googleapis.com/auth/user.emails.read");
            //googleOptions.Scope.Add("https://www.googleapis.com/auth/user.phonenumbers.read");

            app.UseGoogleAuthentication(googleOptions);

            app.UseTwitterAuthentication(new TwitterOptions
            {
                ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g",
                ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI"
            });

            var fb = new Microsoft.AspNetCore.Builder.FacebookOptions()
            {
                AppId = "188223508260529",
                AppSecret = "fa7a0168e96e2c85bcab8d247b1b5b66",
            };
            fb.Scope.Add("email");
            fb.Scope.Add("friends_about_me");
            fb.Scope.Add("friends_photos");

            app.UseFacebookAuthentication(fb);


            app.UseStatusCodePagesWithReExecute("/error");

            app.UseMvcWithDefaultRoute();
            app.UseMvc();

            // Enable middleware to serve generated Swagger as a JSON endpoint
            //app.UseSwagger();

            // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
            //app.UseSwaggerUi();
        }
    }
}

project.json

{
  "dependencies": {
    "AspNet.Security.OAuth.Introspection": "1.0.0-alpha2-final",
    "AspNet.Security.OAuth.Validation": "1.0.0-alpha2-final",
    "Base": "1.0.0-*",
    "DataAccessLayer": "1.0.0-*",
    "Google.Apis": "1.15.0",
    "Google.Apis.Auth": "1.15.0",
    "Google.Apis.Core": "1.15.0",
    "Google.Apis.Drive.v2": "1.15.0.578",
    "Google.Apis.Gmail.v1": "1.15.0.580",
    "Google.Apis.People.v1": "1.15.0.405",
    "IdentityServer4.Contrib.AspNetIdentity": "1.0.0-*",
    "Microsoft.AspNetCore.Authentication.Facebook": "1.0.0",
    "Microsoft.AspNetCore.Authentication.Google": "1.0.0",
    "Microsoft.AspNetCore.Authentication.Twitter": "1.0.0",
    "Microsoft.AspNetCore.Cors": "1.0.0",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0",
    "Microsoft.AspNetCore.Localization": "1.0.0-*",
    "Microsoft.AspNetCore.Mvc": "1.0.0",
    "Microsoft.AspNetCore.Mvc.Localization": "1.0.0-*",
    "Microsoft.AspNetCore.Owin": "1.0.0-rc1-final",
    "Microsoft.AspNetCore.Razor.Tools": {
      "type": "build",
      "version": "1.0.0-preview2-final"
    },
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0",
    "Microsoft.EntityFrameworkCore.Design": "1.0.0-preview2-final",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
    "Microsoft.Extensions.Configuration.CommandLine": "1.0.0",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
    "Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    },
    "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
    "Npgsql": "3.1.5",
    "Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.1",
    "Npgsql.EntityFrameworkCore.PostgreSQL.Design": "1.0.1",
    "NWebsec.AspNetCore.Middleware": "1.0.0-gamma1-15",
    "Swashbuckle": "6.0.0-beta902",
    "IdentityServer4": "1.0.0-beta4-update2",
    "Microsoft.IdentityModel.Tokens": "5.0.0",
    "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
    "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",
    "Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0"
  },

  "tools": {
    "BundlerMinifier.Core": "2.0.238",
    "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true,
    "xmlDoc": false
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "Areas/**/Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "prepublish": [ "bower install", "dotnet bundle" ],
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

你能帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

这是因为您使用的是services.AddMvcCore() services.AddMvc()

只需在ConfigureServices方法中services.TryAddTransient<CorsAuthorizationFilter, CorsAuthorizationFilter>();之后添加services.AddCors

还要检查它在MvcCorsMvcCoreBuilderExtensions

中的完成情况