使用 Google Auth、Angular 4、ASP.Net Core 2 进行身份验证时出现 405
Posted
技术标签:
【中文标题】使用 Google Auth、Angular 4、ASP.Net Core 2 进行身份验证时出现 405【英文标题】:405 when authenticating using Google Auth, Angular 4, ASP.Net Core 2 【发布时间】:2018-02-18 08:44:28 【问题描述】:我正在尝试使用 ASP.NET 中间件通过 Google OAuth 进行身份验证。我了解我遇到的问题是由 CORS 问题引起的,但我似乎无法解决这些问题。
我的启动类配置如下:
public void ConfigureServices(IServiceCollection services)
services.AddCors(options =>
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.AllowCredentials()
);
......
services.AddGoogle(o =>
o.ClientId = Configuration["Authentication:Google:ClientId"];
o.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
o.AuthorizationEndpoint += "?prompt=consent"; // Hack so we always get a refresh token, it only comes on the first authorization response
o.AccessType = "offline";
o.SaveTokens = true;
o.Events = new OAuthEvents()
OnRemoteFailure = ctx =>
ctx.Response.Redirect("/error?FailureMessage=" + UrlEncoder.Default.Encode(ctx.Failure.Message));
ctx.HandleResponse();
return Task.FromResult(0);
;
o.ClaimActions.MapJsonSubKey("urn:google:image", "image", "url");
o.ClaimActions.Remove(ClaimTypes.GivenName);
);
...........
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
loggerFactory.AddConsole();
//if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseCors("CorsPolicy");
app.Use(async (context, next) =>
await next();
// Serve index file and allow Angular to take over routing if (NotFound)
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
context.Request.Path = "/index.html";
await next();
);
app.UseAuthentication();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc();
在我的身份验证控制器中:
// POST: api/auth/ExternalLogin
[HttpPost("loginexternal")]
[AllowAnonymous]
public async Task<IActionResult> LoginExternal([FromBody]string provider)
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
// Request a redirect to the external login provider to link a login for the current user
var redirectUrl = Url.Action(nameof(ExternalLoginCallback));
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
return new ChallengeResult(provider, properties);
调用此函数的我的打字稿角代码:
loginExternal()
const headers = new HttpHeaders( 'Content-Type': 'application/json', 'Accept': 'application/json' );
return this.http.post(this.baseUrl + '/auth/loginexternal', '"Google"', headers: headers )
.map((res: any) =>
localStorage.setItem('auth_token', res.auth_token);
this.loggedIn = true;
this._authNavStatusSource.next(true);
return true;
)
.catch(this.handleError);
这就是响应
在我的 LoginExternal 操作中执行 ChallengeResult 后发生上述响应。
【问题讨论】:
您的代码正在尝试将 JSON 数据跨域发布到https://accounts.google.com/o/oauth2/auth
,这会导致您的浏览器首先向 https://accounts.google.com/o/oauth2/auth
发送 CORS 预检 OPTIONS 请求以询问是否可以获取该跨域邮政。而https://accounts.google.com/o/oauth2/auth
正在响应告诉浏览器,Nope。所以浏览器就停在那里,从不尝试你的 POST 请求。 …无论如何,你无法“解决”这个问题——你的代码正在尝试做https://accounts.google.com
明确不希望你做的事情。
ASP.NET 中间件正在通过控制器执行该请求,不是吗?我的 post 方法只发送到我的控制器。
不,您的前端代码正在尝试执行该 POST 请求。如果它是 ASP.NET 中间件,它就可以工作——因为 ASP.NET 中间件不会强制执行同源策略并强制执行跨域限制。浏览器可以。这就是为什么是您的浏览器向您显示 CORS 错误消息的原因。
那么为什么在使用默认的 ASP.NET MVC 模板和视图中提取身份验证代码时,这段代码可以工作?抱歉,我正在尝试找到解决方法...单步执行调试器时,post 方法会命中我的控制器,该错误仅在中间件 ChellengeResult 方法执行后发生。
这有什么更新吗?我也遇到了同样的问题。
【参考方案1】:
尝试使用 this.document.location.href 甚至 window.location.href 重定向到您的 google 身份验证页面,而不是向您的 .net 核心控制器操作发出 http 请求。
@Injectable()
export class LoginService
//...
constructor(@Inject(DOCUMENT) private document: Document,...)
login()
this.document.location.href 'https://www.mywebsite.com/account/signInWithGoogle';
这是控制器动作中的样子:
public class AccountController : Controller
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
public AccountController(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager)
_signInManager = signInManager;
_userManager = userManager;
public IActionResult SignInWithGoogle()
var authenticationProperties = _signInManager.ConfigureExternalAuthenticationProperties("Google", Url.Action(nameof(HandleExternalLogin)));
return Challenge(authenticationProperties, "Google");
...
向导:https://www.blinkingcaret.com/2018/10/10/sign-in-with-an-external-login-provider-in-an-angular-application-served-by-asp-net-core/
【讨论】:
以上是关于使用 Google Auth、Angular 4、ASP.Net Core 2 进行身份验证时出现 405的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Rest API Google Auth 在 Angular
django-rest-auth + django-allauth + angular2
允许用户在使用angular firebase与google注册时,选择用哪个邮箱注册。
.NET Core 2 WebAPI CORS 与 Angular 4 前端和 Windows Auth 的问题