I am trying to migrate this project https://github.com/asadsahi/AspNetCoreSpa from .net core 1.1 to 2.0, but you have a problem after successfully logging in. After logging in, my GET api calls e. d. to https: // localhost: 44331 / api / profile / test ends with a redirect (302), and I don't know why. I got a carrier token and it looks fine.
Request Header Format: Authorization: Media [Token]
[Route("api/[controller]")] public class ProfileController : BaseController { private readonly UserManager<ApplicationUser> _userManager; private readonly ILogger _logger; public ProfileController(ILoggerFactory loggerFactory, UserManager<ApplicationUser> userManager) { _logger = loggerFactory.CreateLogger<ProfileController>(); _userManager = userManager; } [HttpGet("test")] public async Task<IActionResult> Test() { return Json(ModelState.GetModelErrors()); } } [Authorize] [ServiceFilter(typeof(ApiExceptionFilter))] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] public class BaseController : Controller { public BaseController() { } }
Startup.cs:
public void ConfigureServices(IServiceCollection services) { if (_hostingEnv.IsDevelopment()) { services.AddSslCertificate(_hostingEnv); } else { services.Configure<MvcOptions>(o => o.Filters.Add(new RequireHttpsAttribute())); } services.AddOptions(); services.AddCors(); services.AddLogging(); services.AddResponseCompression(options => { options.MimeTypes = Helpers.DefaultMimeTypes; }); services.AddAuthentication(sharedOptions => { sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(cfg => { cfg.SaveToken = true; cfg.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = Configuration["Authentication:BearerTokens:Issuer"], ValidAudience = Configuration["Authentication:BearerTokens:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:BearerTokens:Key"])), ValidateIssuerSigningKey = false, ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; cfg.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents)); logger.LogError("Authentication failed.", context.Exception); return Task.CompletedTask; }, OnMessageReceived = context => { return Task.CompletedTask; }, OnChallenge = context => { var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(nameof(JwtBearerEvents)); logger.LogError("OnChallenge error", context.Error, context.ErrorDescription); return Task.CompletedTask; } }; }); services.AddDbContext<ApplicationDbContext>(options => { string useSqLite = Startup.Configuration["Data:useSqLite"]; if (useSqLite.ToLower() == "true") { options.UseSqlite(Startup.Configuration["Data:SqlLiteConnectionString"]); } else { options.UseSqlServer(Startup.Configuration["Data:SqlServerConnectionString"]); } options.UseOpenIddict(); }); services.AddIdentity<ApplicationUser, ApplicationRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); //services.ConfigureApplicationCookie(options => //{ // options.LoginPath = "/login"; // options.Events.OnRedirectToLogin = context => // { // if (context.Request.Path.StartsWithSegments("/api") && // context.Response.StatusCode == (int)HttpStatusCode.OK) // { // context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; // } // else // { // context.Response.Redirect(context.RedirectUri); // } // return Task.FromResult(0); // }; //}); services.AddOAuthProviders(); services.AddCustomOpenIddict(); services.AddMemoryCache(); services.RegisterCustomServices(); services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN"); services.AddCustomizedMvc(); // Node services are to execute any arbitrary nodejs code from .net services.AddNodeServices(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "AspNetCoreSpa", Version = "v1" }); }); } public void Configure(IApplicationBuilder app) { app.AddDevMiddlewares(); if (_hostingEnv.IsProduction()) { app.UseResponseCompression(); } app.SetupMigrations(); app.UseXsrf(); app.UseStaticFiles(); app.UseAuthentication(); app.UseMvc(routes => { // http://stackoverflow.com/questions/25982095/using-googleoauth2authenticationoptions-got-a-redirect-uri-mismatch-error routes.MapRoute(name: "signin-google", template: "signin-google", defaults: new { controller = "Account", action = "ExternalLoginCallback" }); routes.MapSpaFallbackRoute( name: "spa-fallback", defaults: new { controller = "Home", action = "Index" }); }); }
My IServiceCollection extensions:
public static IServiceCollection AddCustomizedMvc(this IServiceCollection services) { services.AddMvc(options => { options.Filters.Add(typeof(ModelValidationFilter)); }) .AddJsonOptions(options => { options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; }); return services; } public static IServiceCollection AddOAuthProviders(this IServiceCollection services) { services.AddAuthentication() .AddFacebook(o => { o.AppId = Startup.Configuration["Authentication:Facebook:AppId"]; o.AppSecret = Startup.Configuration["Authentication:Facebook:AppSecret"]; }); services.AddAuthentication() .AddGoogle(o => { o.ClientId = Startup.Configuration["Authentication:Google:ClientId"]; o.ClientSecret = Startup.Configuration["Authentication:Google:ClientSecret"]; }); services.AddAuthentication() .AddTwitter(o => { o.ConsumerKey = Startup.Configuration["Authentication:Twitter:ConsumerKey"]; o.ConsumerSecret = Startup.Configuration["Authentication:Twitter:ConsumerSecret"]; }); services.AddAuthentication() .AddMicrosoftAccount(o => { o.ClientId= Startup.Configuration["Authentication:Microsoft:ClientId"]; o.ClientSecret = Startup.Configuration["Authentication:Microsoft:ClientSecret"]; }); return services; } public static IServiceCollection AddCustomOpenIddict(this IServiceCollection services) {
Here are my packages:
<ItemGroup> <PackageReference Include="AspNet.Security.OAuth.Introspection" Version="2.0.0-*" /> <PackageReference Include="AspNet.Security.OAuth.Validation" Version="2.0.0-*" /> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.AzureAppServicesIntegration" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Facebook" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Twitter" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.0.0" /> <PackageReference Include="Microsoft.AspNetCore.AngularServices" Version="1.1.0-beta-000002" /> <PackageReference Include="AspNet.Security.OAuth.GitHub" Version="1.0.0-beta3-final" /> <PackageReference Include="AspNet.Security.OAuth.LinkedIn" Version="1.0.0-beta3-final" /> <PackageReference Include="OpenIddict" Version="2.0.0-*" /> <PackageReference Include="OpenIddict.EntityFrameworkCore" Version="2.0.0-*" /> <PackageReference Include="OpenIddict.Mvc" Version="2.0.0-*" /> <PackageReference Include="SendGrid" Version="9.9.0" /> <PackageReference Include="MailKit" Version="1.18.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="1.0.0" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="1.0.0" /> <PackageReference Include="Twilio" Version="5.6.3" /> <PackageReference Include="Stripe.net" Version="10.4.0" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.3" /> <PackageReference Include="Webpack" Version="4.0.0" /> <PackageReference Include="Serilog" Version="2.5.0" /> <PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" /> <PackageReference Include="Serilog.Sinks.Seq" Version="3.3.3" /> <PackageReference Include="Bogus" Version="17.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0"> <PrivateAssets>All</PrivateAssets> </PackageReference> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0"> <PrivateAssets>All</PrivateAssets> </PackageReference> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> </ItemGroup>
Here are my logs:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://localhost:44331/api/profile/test application/json; charset=UTF-8 info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization failed for user: (null). info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization failed for user: (null). info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. info: Microsoft.AspNetCore.Mvc.ChallengeResult[1] Executing ChallengeResult with authentication schemes (). info: Microsoft.AspNetCore.Mvc.ChallengeResult[1] Executing ChallengeResult with authentication schemes (). info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[12] AuthenticationScheme: Identity.Application was challenged. info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[12] AuthenticationScheme: Identity.Application was challenged. info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] Executed action AspNetCoreSpa.Server.Controllers.api.ProfileController.Test (AspNetCoreSpa) in 43.3105ms info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] Executed action AspNetCoreSpa.Server.Controllers.api.ProfileController.Test (AspNetCoreSpa) in 43.3105ms info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 67.4133ms 302 infoinfo: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 67.4133ms 302 : Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://localhost:44331/Account/Login? ReturnUrl=%2Fapi%2Fprofile%2Ftest application/json; charset=UTF-8 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://localhost:44331/Account/Login? ReturnUrl=%2Fapi%2Fprofile%2Ftest application/json; charset=UTF-8 info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] Executing action method AspNetCoreSpa.Server.Controllers.HomeController.Index (AspNetCoreSpa) with arguments ((null)) - ModelState is Valid info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] Executing action method AspNetCoreSpa.Server.Controllers.HomeController.Index (AspNetCoreSpa) with arguments ((null)) - ModelState is Valid info: Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor[1] Executing ViewResult, running view at path /Views/Home/Index.cshtml. info: Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor[1] Executing ViewResult, running view at path /Views/Home/Index.cshtml. info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] Executed action AspNetCoreSpa.Server.Controllers.HomeController.Index (AspNetCoreSpa) in 13.2746ms info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2] Executed action AspNetCoreSpa.Server.Controllers.HomeController.Index (AspNetCoreSpa) in 13.2746ms info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 79.2352ms 200 text/html; charset=utf-8 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 79.2352ms 200 text/html; charset=utf-8
Interesting about the following line:
User authorization failed: (null)
It has already been found that the ASP.NET Kernel authorization failed for the user: (null) but there is no answer yet, and I think this is a .net core 1 kernel problem.
Thank you for your help!
Regards Simon