c# - 具有社交登录且无 MVC 依赖项的 ASP.NET WebAPI 2.2 SPA

标签 c# asp.net .net asp.net-web-api

我一直在设计一个应用程序,它只是一个静态服务的客户端页面,旨在使用不记名 token 通过支持 API 进行身份验证,但是最近我一直在尝试向后端添加社交登录选项,但发现它非常有用很难找到任何不使用 MVC 依赖项的示例,我希望尽可能避免。

这个问题对入门很有帮助:ASP.NET Web API social authentication for Web and Mobile

但是我一直在努力让我的项目在同一个庄园内工作,基本上在我引用的问题中他配置了一个 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 帐户 Controller 中,他有以下操作:

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

在这个例子中,我无法弄清楚 RouteAttribute (模板)的第一个参数在项目中实际引用了什么,如果有的话,有人可以解释一下它在做什么这个语境?

现在,当运行问题中提供的示例项目时,向“​​api/Account/ExternalLogin”发送 GET 请求时,请求将在他的 API 帐户 Controller 中的操作上处理,我认为它与 有关OverrideAuthentication 但我在这里有点超出了我的理解范围,并且正在努力寻找该属性其他用法的有力示例。

但是我相当确定我已经按照他描述的方式正确配置了我的 WebAPI 项目,但是当向我的 OAuthAuthorizationServerOptions.AuthorizeEndpointPath 发送 GET 请求时,它不是在我的 API 帐户 Controller 上处理的,而是取而代之的是我的 OAuthAuthorizationServerProvider 实现,它返回“invalid_request”错误。

谁能想到我可能忽略的导致我的 API 帐户 Controller 操作被忽略的事情?

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

感谢您的帮助, 亚历克斯。

最佳答案

在没有实际看到您发出的 GET 请求的情况下,我只能假设它们不符合 OAuth 提供者的期望。

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

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

反编译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 Controller 方法的请求:

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

附言就 Controller 上的路由属性而言,"template"字段指定将用作模板的字符串,用于匹配传入请求 URI,以确定应将请求路由到何处。

附言可以找到反编译片段的实际源代码 here

关于c# - 具有社交登录且无 MVC 依赖项的 ASP.NET WebAPI 2.2 SPA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39432029/

相关文章:

c# - CLR 类型到 EDM 类型的映射对于 EF 6 和 5 不明确?

c# - 获取图表值

c# - 为什么 WCF 服务作为 PID 4 (SYSTEM) 而不是托管它的进程的 PID 进行监听?

.net - 在vb.net中,如何从数据表中获取列名

c# - 将数据访问层移动到 WCF 服务

c# - 使用 .Net 写入 COM 端口

c# - 实体可以附加到以前未附加的 ISession 吗?

c# - 按下鼠标按钮时如何防止 mousemove 事件?

javascript - 脚本在 mvc4 中不起作用

asp.net - 绑定(bind)字段样式