我已经在stackoverflow上阅读了其他框架的类似问题,但没有一个涉及如何使用ASP.NET Core 2.1解决此问题。我假设某处我将需要修改由库生成的访问令牌,但是我看不到它的简单钩子。
导航到标有[Authorize]的控制器/操作后,错误产生以下异常:
Exception: OAuth token endpoint failure: Status: BadRequest;Headers: Cache- Control: no-store
Connection: keep-alive
Date: Sun, 01 Jul 2018 20:26:11 GMT
Pragma: no-cache
WWW-Authenticate: OAuth "Facebook Platform" "invalid_code" "This authorization code has been used."
Strict-Transport-Security: max-age=15552000; x-fb-trace-id: FUP+X7GzCHR
x-fb-rev: 4066065
facebook-api-version: v2.6
Access-Control-Allow-Origin: *
X-FB-Debug: 97aI6xVBbJLooeNj3qmNCw9NFifMBvYire/pA0R6dCH5BqWcJ9Vc9rJK+KWvwiNiTXV4PX5ASLbEkbCGgqtCmg==
;Body: {"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100,"fbtrace_id":"FUP+X7GzCHR"}};
Unknown location
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler+<HandleRequestAsync>d__12.MoveNext()
我的Startup.cs如下:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddDbContext<FacebookIdentityContext>();
//services.AddDataProtection().PersistKeysToAzureBlobStorage(new Uri(Configuration["Blob:Uri"])).ProtectKeysWithDpapi();
services.AddCors(options =>
{
options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
services.AddIdentity<FacebookUser, IdentityRole<int>>().AddEntityFrameworkStores<FacebookIdentityContext>().AddDefaultTokenProviders();
services.AddAuthentication().AddFacebook(fb =>
{
fb.AppId = Configuration["Facebook:AppId"];
fb.AppSecret = Configuration["Facebook:AppSecret"];
fb.CallbackPath += "/";
});
services.AddMvc().AddControllersAsServices();
Container container = new Container();
container.Configure(config =>
{
CosmosDataToken graphToken = new CosmosDataToken(new Uri(Configuration["GraphDB:Uri"]), Configuration["GraphDB:Key"], Configuration["GraphDB:Database"], Configuration["GraphDB:DocumentCollection"]);
config.For<CosmosDataToken>().Add(graphToken).Named("Graph");
config.For<IBrandDataAdapter>().Use<BrandDataAdapter>().Ctor<CosmosDataToken>().Named("Graph");
config.For<IBrandBusinessLogic>().Use<BrandBusinessLogic>();
config.Populate(services);
config.For<IContainer>().Use(container);
});
return container.GetInstance<IServiceProvider>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseAuthentication();
app.UseStaticFiles();
app.UseCors("AllowAll");
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
AccounController.cs:
[Route("[controller]/[action]")]
public class AccountController : Controller
{
[HttpGet]
public IActionResult SignIn()
{
var redirectUrl = Url.Action(nameof(HomeController.Index), "Home");
return Challenge(
new AuthenticationProperties { RedirectUri = redirectUrl },
FacebookDefaults.AuthenticationScheme);
}
[HttpGet]
public IActionResult Login(string returnUrl)
{
return Challenge(
new AuthenticationProperties { RedirectUri = returnUrl }, FacebookDefaults.AuthenticationScheme);
}
}
根据要求:Raw Stack Trace(2018年7月9日)
System.Exception: An error was encountered while handling the remote login. ---> System.Exception: OAuth token endpoint failure: Status: BadRequest;Headers: Cache-Control: no-store
Connection: keep-alive
Date: Tue, 10 Jul 2018 02:07:33 GMT
Pragma: no-cache
WWW-Authenticate: OAuth "Facebook Platform" "invalid_code" "This authorization code has been used."
Strict-Transport-Security: max-age=15552000; preload
x-fb-trace-id: GGIG00tEoLq
x-fb-rev: 4083489
facebook-api-version: v2.6
Access-Control-Allow-Origin: *
X-FB-Debug: oRwbzflr375r3JhjSp0V1K1iP3+vI5m/kHUCsr5CPHwHv68Waz4eydZ8cw5cTCCT2KUo6Z8la42syKtNPuWfxQ==
;Body: {"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100,"fbtrace_id":"GGIG00tEoLq"}};
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.<HandleRequestAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
和IIS日志:
2018-07-10 02:07:33 ::1 GET /signin-facebook/ code=AQACzBL6QlPjzfEBoB2L9LEbMXgdxw3KNgcBc-8fv2RGHAtfa9bGCqWZ-efFgEPv_mx1Xaphi6z0Ok6cNGDArIWiwdtIw_tB2r6EaQ7TyEsov5fajemTgYZtsgJXEOtpOo0YQmBDROIMtaKEAREsJFeN3eR3QYqEedadgSRikCB-gFVKCSalPXVQubHGzPRQHOl16u-zNNe4sJJlBX8G0LZeJ7tziCnIiexfTB_zBWvFrgjggfUPtlFV2VLWLxH55O3xD1sZxY2xFTy01P4Tb4ENAurvAh2techvnV4uDobSyrSVoylGSKEqTHdalENlqKU&state=CfDJ8Fal1oNbU75Jg6-R34J8E0YhIDy-BtCBqI_xTclwY43ARUtMiTWDmco_N7wJNTbUoHedtAe0yVBR2r9sV_sOTayIgaJEkRuqWyuO0i5Yh6vB7pbUX4krFRcwIzDbVSBGxPwBzQSOqtLPoY8KlKjmN70sooi_fQqq3OIcFynOe8UVd-mMtodbu3fdOz0kVpdO-khCscC-R4p78IJiWzqAN_Xsd_MR4ihTKbWSBfGRVreU 44392 - ::1 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/64.0.3282.140+Safari/537.36+Edge/17.17134 - 500 0 0 245
编辑2018年7月12日: 可以在以下网址找到具有相同错误的完整示例:https://github.com/jlind0/TestFacebookAuth
答案 0 :(得分:2)
我弄清楚了你的问题。您的AccountController
出问题了。当您致电Challenge
时,用户将重定向到Facebook,并在成功登录后返回。当用户返回时,其凭证将添加IdentityConstants.ExternalScheme
。在这里,您还需要使用SignIn
来调用IdentityConstants.ApplicationScheme
。因此,您需要一个回调方法来处理此问题。
这就是您的AccountController
[HttpGet]
public IActionResult SignIn()
{
var redirectUrl = Url.Action(nameof(HomeController.Index), "Home");
return Login(redirectUrl);
}
[HttpGet]
public IActionResult Login(string returnUrl)
{
var redirectUrl = Url.Action(nameof(AccountController.LoginCallback), "Account", new { returnUrl = returnUrl });
return Challenge(
new AuthenticationProperties { RedirectUri = redirectUrl, }, FacebookDefaults.AuthenticationScheme);
}
[HttpGet]
public async Task<IActionResult> LoginCallback(string returnUrl)
{
var authenticateResult = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme);
await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, new System.Security.Claims.ClaimsPrincipal(authenticateResult.Ticket.Principal.Identity));
return LocalRedirect(returnUrl);
}
但是我强烈建议您使用该模板作为用户管理器。