【问题标题】:405 when authenticating using Google Auth, Angular 4, ASP.Net Core 2使用 Google Auth、Angular 4、ASP.Net Core 2 进行身份验证时出现 405
【发布时间】: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 方法执行后发生。
  • 这有什么更新吗?我也遇到了同样的问题。

标签: angular authentication asp.net-core cors


【解决方案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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-06
    • 2022-01-23
    • 2017-12-13
    • 2018-05-13
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    相关资源
    最近更新 更多