Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#基于Facebook令牌的Web Api身份验证_C#_Facebook_Owin - Fatal编程技术网

C#基于Facebook令牌的Web Api身份验证

C#基于Facebook令牌的Web Api身份验证,c#,facebook,owin,C#,Facebook,Owin,我正在尝试将Facebook身份验证添加到一个C#web api项目中,该项目使用默认的web api模板,该模板应该与一个单独的Javascript web界面(使用React)一起工作。 但是,我遇到了无法将授权令牌从后端传递到前端的问题。有什么合适的方法吗 ** 详细描述我迄今为止所取得的成就: ** 前端端口为3000,后端端口为44378 我使用的顺序如下所示: 1) 首先,获取所有可用的登录提供程序 GET /api/Account/ExternalLogins?returnUrl=

我正在尝试将Facebook身份验证添加到一个C#web api项目中,该项目使用默认的web api模板,该模板应该与一个单独的Javascript web界面(使用React)一起工作。 但是,我遇到了无法将授权令牌从后端传递到前端的问题。有什么合适的方法吗

**

详细描述我迄今为止所取得的成就: **

前端端口为3000,后端端口为44378

我使用的顺序如下所示:

1) 首先,获取所有可用的登录提供程序

GET /api/Account/ExternalLogins?returnUrl=%2F&generateState=true
2) 然后,使用与Facebook提供商关联的Url

/api/Account/ExternalLogin?provider=Facebook&response_type=token&redirect_uri=https%3A%2F%2Flocalhost%3A44378%2F&state=KXiWds49DMtXLqwrPFsfvus6VfJRh4Gr5dQFq5Q10nE1
由此,我们获得了几个到Facebook和本地后端的重定向,如下所示:

在此之后,地址如下所示:

https://localhost:44378/#access_token=[...]&token_type=bearer&expires_in=1209600&state=qrnh0GIG8ZTWTGh4e603gWLaE7E3GBUK-7dLURg6vus1
据我所知,这是一个与Facebook没有直接联系的本地访问令牌

3) 这就是我的死胡同。重定向URL位于后端,因此前端无法访问此令牌。如果我将令牌作为Authorization:Bearer手动复制粘贴到请求头中,我可以访问Web Api,但它没有传递回前端组件,因此我被卡住了

需要注意的是,在所有重定向之后,后端会根据用户是否拥有本地帐户来设置cookie:.AspNet.ExternalCookie(如果他没有),以及.AspNet.Cookies(如果他有),但我无法找到它们的任何用途

所以问题是:有没有办法将本地访问令牌传递给前端组件?

为完整起见,以下是一些相关的代码部分:

Startup.Auth.cs

使用系统;
使用Microsoft.AspNet.Identity;
使用Microsoft.Owin;
使用Microsoft.Owin.Security.Cookies;
使用Microsoft.Owin.Security.Facebook;
使用Microsoft.Owin.Security.OAuth;
使用Owin;
使用WebApplication4.Providers;
使用WebApplication4.模型;
命名空间WebApplication4
{
公共部分类启动
{
公共静态OAuthAuthorizationServerOptions OAuthOptions{get;private set;}
公共静态字符串PublicClientId{get;private set;}
public void ConfigureAuth(IAppBuilder应用程序)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext(ApplicationUserManager.Create);
app.UseCookieAuthentication(新的CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
//为基于OAuth的流配置应用程序
PublicClientId=“self”;
OAuthOptions=新的OAuthAuthorizationServerOptions
{
TokenEndpointPath=新路径字符串(“/Token”),
Provider=新的ApplicationAuthProvider(PublicClientId),
AuthorizeEndpointPath=新路径字符串(“/api/Account/ExternalLogin”),
AccessTokenExpireTimeSpan=TimeSpan.FromDays(14),
//在生产模式下,设置AllowInsecureHttp=false
AllowInsecureHttp=true
};
var facebookOptions=new FacebookAuthenticationOptions()
{
AppId=“*”,
AppSecret=“*”,//隐藏的代码
};
app.UseFacebookAuthentication(facebookOptions);
}
}
}
AccountController.cs-仅外部登录方法

[重写身份验证]
[主机身份验证(DefaultAuthenticationTypes.ExternalCookie)]
[异名]
[路由(“外部登录”,Name=“外部登录”)]
公共异步任务GetExternalLogin(字符串提供程序,字符串错误=null)
{
if(错误!=null)
{
返回重定向(Url.Content(“~/”+“#error=“+Uri.EscapeDataString(error));
}
如果(!User.Identity.IsAuthenticated)
{
返回新的ChallengeResult(提供程序,此);
}
ExternalLoginData externalLogin=ExternalLoginData.FromIdentity(User.Identity作为索赔实体);
if(externalLogin==null)
{
返回InternalServerError();
}
if(externalLogin.LoginProvider!=提供程序)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
返回新的ChallengeResult(提供程序,此);
}
ApplicationUser user=await UserManager.FindAsync(新用户登录信息(externalLogin.LoginProvider,
外部登录(ProviderKey));
bool hasRegistered=user!=null;
如果(已注册)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
ClaimsIdentity oAuthIdentity=等待用户.GenerateUserIdentityAsync(UserManager,
OAuthDefaults.AuthenticationType);
ClaimSideEntity cookieIdentity=等待用户.GenerateUserIdentity异步(UserManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties=ApplicationAuthProvider.CreateProperties(user.UserName);
身份验证.签名(属性、oAuthIdentity、cookieIdentity);
}
其他的
{
IEnumerable claims=externalLogin.GetClaims();
ClaimsIdentity identity=newclaimsidentity(声明,OAuthDefaults.AuthenticationType);
身份验证。签名(身份);
}
返回Ok();
}
“据我所知,这是一个与Facebook没有直接连接的本地访问令牌”-不,这是FB访问令牌。“重定向URL位于后端,因此前端无法访问此令牌”-URL的哈希部分仅为客户端构造,甚至无法发送到服务器…您可以选择在前端捕获此内容,或选择不同的响应类型,获取一个代码,然后通过服务器端API调用交换令牌,“不,这是FB访问令牌”——你确定吗?我使用这个令牌作为API本身的授权承载,这就是为什么我想到FB
using System;
using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Facebook;
using Microsoft.Owin.Security.OAuth;
using Owin;
using WebApplication4.Providers;
using WebApplication4.Models;

namespace WebApplication4
{
    public partial class Startup
    {
        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

        public static string PublicClientId { get; private set; }

        public void ConfigureAuth(IAppBuilder app)
        {
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Configure the application for OAuth based flow
            PublicClientId = "self";
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                // In production mode set AllowInsecureHttp = false
                AllowInsecureHttp = true
            };

            var facebookOptions = new FacebookAuthenticationOptions()
            {
                AppId = "*",
                AppSecret = "*", //codes hidden
            };

            app.UseFacebookAuthentication(facebookOptions);
        }
    }
}
[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();
}