ASP.. NET WebAPI 2.2 SPA,带有社交登录,没有MVC依赖

本文关键字:登录 依赖 没有 MVC NET WebAPI SPA ASP | 更新日期: 2023-09-27 18:06:41

我一直在设计一个应用程序,它只是一个静态服务的客户端页面,旨在使用承载令牌与后台API进行身份验证,但最近我一直在尝试将社交登录选项添加到后端,但发现很难找到任何不使用MVC依赖关系的例子,我想尽可能避免。

这个问题对入门有很大帮助:Web和移动的。NET Web API社会认证

然而,我一直在努力让我的项目在同一个庄园工作,基本上在我参考的问题中,他已经配置了这样的OAuthAuthorizationServerOptions.AuthorizeEndpointPath:

OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/token"),
                Provider = new ApplicationOAuthProvider(PublicClientId),
                AuthorizeEndpointPath = new PathString("/api/account/externallogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                //AllowInsecureHttp = false
            };

同样在他的后台api帐户控制器中,他有以下动作:

[OverrideAuthentication]
        [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
        [AllowAnonymous]
        [Route("ExternalLogin", Name = "ExternalLogin")]
        public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)

在这个例子中,我没能弄清楚RouteAttribute(模板)的第一个参数在项目中实际引用的是什么,如果有的话,有人可能会解释它在这种情况下做什么?

现在,当运行问题中提供的示例项目发送GET请求到'api/Account/ExternalLogin'时,请求将在他的api帐户控制器的动作上处理,我认为它与OverrideAuthentication有关,但我在这里有点超出我的深度,并努力寻找这个属性的其他用法的强有力的例子。

然而,我相当肯定我已经正确地配置了我的WebAPI项目,他所描述的方式,但是,当发送一个GET请求到我的OAuthAuthorizationServerOptions.AuthorizeEndpointPath时,它不是在我的API帐户控制器上处理的,而是由我的OAuthAuthorizationServerProvider的实现返回'invalid_request'错误。

有人能想到的东西,我可能会忽略这是导致我的API帐户控制器动作被忽略?

我也读过这篇文章,但它似乎是用旧版本的WebAPI写的:https://thompsonhomero.wordpress.com/2015/01/21/creating-a-clean-web-api-2-project-with-external-authentication-part-2/

谢谢你的帮助,亚历克斯。

ASP.. NET WebAPI 2.2 SPA,带有社交登录,没有MVC依赖

如果没有实际看到正在发出的GET请求,我只能假设它们没有满足OAuth提供程序的期望。

提供者首先验证正在发出的请求,然后将控制权交给端点的控制器。您的代码很可能是正确的,只是请求格式不正确。

我做了一个新项目,并且能够通过向AuthorizeEndpointPath发出get请求来复制您描述的问题。不幸的是,这里没有太多的原因,但是如果你反编译源代码,或者设法找到源代码,你可以看到这里发生了什么。

反编译ApplicationOAuthProvider.ValidateClientRedirectUri的调用代码,我得到:

  await this.Options.Provider.ValidateClientRedirectUri(clientContext);
  if (!clientContext.IsValidated)
  {
    LoggerExtensions.WriteVerbose(this._logger, "Unable to validate client information");
    flag = await this.SendErrorRedirectAsync(clientContext, (BaseValidatingContext<OAuthAuthorizationServerOptions>) clientContext);
  }
  else
  {
    OAuthValidateAuthorizeRequestContext validatingContext = new OAuthValidateAuthorizeRequestContext(this.Context, this.Options, authorizeRequest, clientContext);
    if (string.IsNullOrEmpty(authorizeRequest.ResponseType))
    {
      LoggerExtensions.WriteVerbose(this._logger, "Authorize endpoint request missing required response_type parameter");
      validatingContext.SetError("invalid_request");
    }
    else if (!authorizeRequest.IsAuthorizationCodeGrantType && !authorizeRequest.IsImplicitGrantType)
    {
      LoggerExtensions.WriteVerbose(this._logger, "Authorize endpoint request contains unsupported response_type parameter");
      validatingContext.SetError("unsupported_response_type");
    }
    else
      await this.Options.Provider.ValidateAuthorizeRequest(validatingContext);
    if (!validatingContext.IsValidated)
    {
      flag = await this.SendErrorRedirectAsync(clientContext, (BaseValidatingContext<OAuthAuthorizationServerOptions>) validatingContext);
    }
    else
    {
      this._clientContext = clientContext;
      this._authorizeEndpointRequest = authorizeRequest;
      OAuthAuthorizeEndpointContext authorizeEndpointContext = new OAuthAuthorizeEndpointContext(this.Context, this.Options, authorizeRequest);
      await this.Options.Provider.AuthorizeEndpoint(authorizeEndpointContext);
      flag = authorizeEndpointContext.IsRequestCompleted;
    }
  }

在这段代码中,您可以看到,如果请求已经被验证,并且没有提供请求指定的ResponseType,它将上下文的错误设置为"invalid_request"。

我能够使用以下请求URI成功地获得通过ExternalLogin控制器方法的请求:

http://localhost:18086/api/Account/ExternalLogin?provider=none&client_id=self&redirect_uri=http://localhost:18086/&response_type=token`

注:至于控制器上的路由属性,"template"字段指定了一个字符串,该字符串将被用作模板来匹配传入请求的uri,以确定应该将请求路由到哪里。

P.P.S.反编译代码段的实际源代码可以在这里找到