ASP.NET WEB API外部登录

时间:2016-11-08 15:19:43

标签: c# asp.net asp.net-mvc asp.net-identity

我使用Visual Studio 2013项目向导在ASP.NET中创建WEB API项目。它为社交登录创建了这个功能:

// GET api/Account/ExternalLogin
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
[AllowAnonymous]
[Route("ExternalLogin", Name = "ExternalLogin")]
public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
{
    if (error != null)
    {
        return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
    }

    if (!User.Identity.IsAuthenticated)
    {
        return new ChallengeResult(provider, this);
    }

    ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);

    if (externalLogin == null)
    {
        return InternalServerError();
    }

    if (externalLogin.LoginProvider != provider)
    {
        Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
        return new ChallengeResult(provider, this);
    }

    ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
        externalLogin.ProviderKey));

    bool hasRegistered = user != null;

    if (hasRegistered)
    {
        Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);

         ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
            OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
            CookieAuthenticationDefaults.AuthenticationType);

        AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
        Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
    }
    else
    {
        IEnumerable<Claim> claims = externalLogin.GetClaims();
        ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
        Authentication.SignIn(identity);
    }

    return Ok();
}

然后我用C#写了一个客户端代码来调用这个函数:

public async Task LogInAsync(string url, string provider)
{
    using (HttpClient client = new HttpClient())
    {
      string request = url + "/api/Account/ExternalLogin";
      var query = HttpUtility.ParseQueryString(string.Empty);
      query["provider"] = provider;
      query["error"] = "";
      request += "?" + query.ToString();

      HttpResponseMessage responseMessage = await client.GetAsync(request);
      if (responseMessage.IsSuccessStatusCode)
      {
        string responseContent = await responseMessage.Content.ReadAsStringAsync();
      }
    }
}

奇怪的是,我从服务器收到此错误响应:

  

StatusCode:400,ReasonPhrase:&#39;错误请求&#39;,版本:1.1,内容:   System.Net.Http.StreamContent,Headers:{Pragma:no-cache
  X-SourceFiles:   =?UTF-8 2 B 4 RTpcUHJvamVjdFxEYXRpbmdcRGF0aW5nLlNlcnZlclxhcGlcQWNjb3VudFxFeHRlcm5hbExvZ2lu?=   缓存控制:无缓存日期:2016年11月8日星期二15:12:33 GMT
  服务器:Microsoft-IIS / 8.0 X-Powered-By:ASP.NET Content-Length:24   内容类型:text / plain; charset = UTF-8到期:-1}

当我尝试在Web浏览器中导航相应的链接时,会出现相同的错误。在服务器调试时,不会命中此功能的相应入口点。我做错了什么?它是GET动词,所以我应该能够以任何一种方式成功访问它。

最让我感到困惑的是,默认情况下,这个功能包含在每个WEB API项目中,但我找不到任何参考或提及人们在实践中如何使用它。

2 个答案:

答案 0 :(得分:0)

由于您正在使用其中一个模板,因此我假设您的项目使用带有多个重写方法的派生OAuthAuthorizationServerProvider。在那些中删除一些断点,因为这可能是它失败的地方。

答案 1 :(得分:0)

默认情况下,OAuthServerOptions具有以下内容:

AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin")

只需摆脱该行,您的ExternalLOgin端点将可以正常工作。

文件:Startup.Auth.cs