ASP.NET Web API和身份与Facebook登录

ASP.NET Web API和身份与Facebook登录,facebook,asp.net-web-api,asp.net-identity,facebook-android-sdk,facebook-ios-sdk,Facebook,Asp.net Web Api,Asp.net Identity,Facebook Android Sdk,Facebook Ios Sdk,在ASP.NET身份的Facebook身份验证流中,Facebook OAuth对话框将代码而非访问令牌附加到重定向\u url,以便服务器可以通过以下方式将此代码交换为访问令牌: http://localhost:49164/signin-facebook?code=…&state=… 我的问题是,我的客户端是一个使用Facebook SDK的移动应用程序,这会直接给我一个访问令牌。Facebook说使用SDK总是会给你一个访问令牌,所以我可以直接给ASP.NETWebAPI吗 我知

在ASP.NET身份的Facebook身份验证流中,Facebook OAuth对话框将代码而非访问令牌附加到
重定向\u url
,以便服务器可以通过以下方式将此代码交换为访问令牌:

http://localhost:49164/signin-facebook?code=…&state=…
我的问题是,我的客户端是一个使用Facebook SDK的移动应用程序,这会直接给我一个访问令牌。Facebook说使用SDK总是会给你一个访问令牌,所以我可以直接给ASP.NETWebAPI吗


我知道这不是很安全,但这有可能吗?

我不知道你是否找到了解决方案,但我正在尝试做类似的事情,我仍然在把拼图的各个部分拼在一起。我试图将此作为评论而不是回答,因为我没有提供真正的解决方案,但太长了

显然,OAuth中的所有WebAPI Owin选项都是基于浏览器的,也就是说,它们需要大量不适合本机移动应用程序的浏览器重定向请求(如我的情况所需)。我仍在调查和试验,但作为登录Facebook的用户,使用Facebook SDK接收的访问令牌可以通过API直接验证,方法是对
/me
端点进行图形调用

通过使用图形调用返回的信息,您可以检查用户是否已经注册。最后,我们需要登录用户,可能使用Owin的
Authentication.sign
方法,返回一个将用于所有后续API调用的承载令牌

编辑:事实上,我搞错了。承载令牌在调用
/token
端点时发出,该端点在输入时接受如下内容:

grant_type=password&username=Alice&password=password123
这里的问题是,我们没有一个密码,这是OAuth机制的全部要点,所以我们如何才能调用
/Token
端点

更新:我终于找到了一个可行的解决方案,以下是我必须添加到现有类中以使其可行的内容:

Startup.Auth.cs

公共部分类启动
{
/// 
///添加此部分是为了使API端点能够对接受Facebook访问令牌的用户进行身份验证
/// 
静态启动()
{
PublicClientId=“self”;
//UserManagerFactory=()=>新的UserManager(新的UserStore(新的ApplicationDbContext());
UserManagerFactory=()=>
{
var userManager=newusermanager(newuserstore(newapplicationdbcontext());
userManager.UserValidator=newuservalidator(userManager){AllowOnlyAlphanumericUserNames=false};
返回userManager;
};
OAuthOptions=新的OAuthAuthorizationServerOptions
{
TokenEndpointPath=新路径字符串(“/Token”),
Provider=新的ApplicationAuthProvider(PublicClientId,UserManagerFactory),
AuthorizeEndpointPath=新路径字符串(“/api/Account/ExternalLogin”),
AccessTokenExpireTimeSpan=TimeSpan.FromDays(14),
AllowInsecureHttp=true
};
OAuthBearerOptions=新的OAuthBeareAuthenticationOptions();
OAuthBeareOptions.AccessTokenFormat=OAuthOptions.AccessTokenFormat;
OAuthBeareOptions.AccessTokenProvider=OAuthOptions.AccessTokenProvider;
OAuthBeareOptions.AuthenticationMode=OAuthOptions.AuthenticationMode;
OAuthBeareOptions.AuthenticationType=OAuthOptions.AuthenticationType;
OAuthBeareOptions.Description=OAuthOptions.Description;
OAuthBeareOptions.Provider=新的CustomBeareAuthenticationProvider();
OAuthBearOptions.SystemClock=OAuthOptions.SystemClock;
}
公共静态OAuthBeareAuthenticationOptions OAuthBeareOptions{get;private set;}
公共静态OAuthAuthorizationServerOptions OAuthOptions{get;private set;}
公共静态函数UserManagerFactory{get;set;}
公共静态字符串PublicClientId{get;private set;}
//有关配置身份验证的详细信息,请访问http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder应用程序)
{
[初始样板代码]
OAuthBeareAuthenticationExtensions.UseAuthBeareAuthentication(应用程序,OAuthBeareOptions);
[更多样板代码]
}
}
公共类CustomBeareAuthenticationProvider:OAuthBeareAuthenticationProvider
{
公共覆盖任务ValidateIdentity(OAuthValidateIdentityContext上下文)
{
var索赔=context.Ticket.Identity.claims;
if(claims.Count()==0 | | claims.Any(claim=>claim.Issuer!=“Facebook”&&claim.Issuer!=“地方当局”))
context.Rejected();
返回Task.FromResult(空);
}
}
AccountController
中,我添加了以下操作:

[HttpPost]
[异名]
[路由(“FacebookLogin”)]
公共异步任务FacebookLogin(字符串令牌)
{
[验证输入的代码…]
var tokenExpirationTimeSpan=TimeSpan.FromDays(14);
ApplicationUser用户=null;
//获取fb访问令牌并对/me端点进行图形调用
//检查用户是否已注册
//如果是,则检索用户
//如果没有,请注册
//最后登录用户:这是创建承载令牌和验证用户的代码的关键部分
var identity=newclaimsidentity(Startup.oauthBeareOptions.AuthenticationType);
identity.AddClaim(新声明(ClaimTypes.Name,user.Id,null,“Facebook”);
//此声明用于正确填充用户id
identity.AddClaim(新的声明(ClaimTypes.NameIdentifier,user.Id,null,“LOCAL_AUTHORITY”);
AuthenticationTicket票证=新的AuthenticationTicket(标识,新的AuthenticationProperties());
var currentUtc=new Microsoft.Owin.Infrastructure.SystemClock().UtcNow;
ticket.Properties.IssuedUtc=curren
[AllowAnonymous, HttpGet]
async Task<IHttpActionResult> ObtainLocalAccessToken(string provider, string externalAccessToken)

[AllowAnonymous, HttpPost]
async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)