gpt4 book ai didi

c# - ASP.NET Core 2 API 调用被重定向 (302)

转载 作者:太空狗 更新时间:2023-10-29 17:47:40 24 4
gpt4 key购买 nike

我正在尝试迁移这个项目 https://github.com/asadsahi/AspNetCoreSpa从 .net core 1.1 到 2.0 但成功登录后出现问题。登录后我的 GET api 调用 e。 G。至 https://localhost:44331/api/profile/test以重定向 (302) 结束,我不知道为什么。我收到了一个不记名 token ,看起来不错。

请求头格式:授权:不记名[ 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()
{
}
}

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

我的 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)
{

// Configure Identity to use the same JWT claims as OpenIddict instead
// of the legacy WS-Federation claims it uses by default (ClaimTypes),
// which saves you from doing the mapping in your authorization controller.
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
options.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
options.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;

});

// Register the OpenIddict services.
services.AddOpenIddict()
// Register the Entity Framework stores.
.AddEntityFrameworkCoreStores<ApplicationDbContext>()

// Register the ASP.NET Core MVC binder used by OpenIddict.
// Note: if you don't call this method, you won't be able to
// bind OpenIdConnectRequest or OpenIdConnectResponse parameters.
.AddMvcBinders()

// Enable the token endpoint.
.EnableTokenEndpoint("/connect/token")

// Enable the password and the refresh token flows.
.AllowPasswordFlow()
.AllowRefreshTokenFlow()

// During development, you can disable the HTTPS requirement.
.DisableHttpsRequirement()

// Register a new ephemeral key, that is discarded when the application
// shuts down. Tokens signed using this key are automatically invalidated.
// This method should only be used during development.
.AddEphemeralSigningKey();

// On production, using a X.509 certificate stored in the machine store is recommended.
// You can generate a self-signed certificate using Pluralsight's self-cert utility:
// https://s3.amazonaws.com/pluralsight-free/keith-brown/samples/SelfCert.zip
//
// services.AddOpenIddict()
// .AddSigningCertificate("7D2A741FE34CC2C7369237A5F2078988E17A6A75");
//
// Alternatively, you can also store the certificate as an embedded .pfx resource
// directly in this assembly or in a file published alongside this project:
//
// services.AddOpenIddict()
// .AddSigningCertificate(
// assembly: typeof(Startup).GetTypeInfo().Assembly,
// resource: "AuthorizationServer.Certificate.pfx",
// password: "OpenIddict");

return services;
}

public static IServiceCollection AddCustomDbContext(this IServiceCollection services)
{
// Add framework services.

return services;
}

public static IServiceCollection RegisterCustomServices(this IServiceCollection services)
{
// New instance every time, only configuration class needs so its ok
services.Configure<SmsSettings>(options => Startup.Configuration.GetSection("SmsSettingsTwillio").Bind(options));
services.AddTransient<UserResolverService>();
services.AddTransient<IEmailSender, EmailSender>();
services.AddTransient<ISmsSender, SmsSender>();
services.AddScoped<ApiExceptionFilter>();
return services;
}

这是我的包裹:

<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>

这是我的日志:

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

我想知道下面一行:

用户授权失败:(null)

已经找到这个Authorization failed for user: (null)但目前还没有答案,我认为这是 .NET Core 1 的问题。

最佳答案

当您调用 AddIdentity 时,它会添加 Cookie 身份验证,这会覆盖您预期的 JWT 持有者身份验证。解决此问题的一种方法是在设置 JWT 身份验证之前移动 AddIdentity 调用。以下是对我有用的代码:

// setup identity
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<MyMoneyDbContext>()
.AddDefaultTokenProviders();

// setup Jwt authentication
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, jwtBearerOptions =>
{
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
...

另一种选择是使用 AddIdentityCore,但我从未尝试过。

关于c# - ASP.NET Core 2 API 调用被重定向 (302),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46036468/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com