c# - 使用 OpenIdConnectServer 并尝试通过 API 服务连接到 Facebook

标签 c# facebook asp.net-core openid-connect aspnet-contrib

我正在尝试找出一种方法,使我的 API 能够将来自 Facebook 的用户关联到我的身份用户。

应用上下文

我正在开发一个移动应用程序(在 Xamarin 中),需要使用用户名/密码和 Facebook 进行登录。我已经设置了 app.UseOpenIdConnectServer 配置并创建了自定义 Provider,所以我的应用程序已经可以使用用户名/密码了。

现在我正在尝试与 Facebook 集成,但没有找到实现此目的的方法。

我正在考虑在 API 中创建一个服务,例如 /api/auth/login-facebook/ 从 Facebook 传递 access-token 但我需要返回我的 API 应用程序的 access-token 到移动应用程序,以便移动应用程序可以调用所有其他需要授权的服务。

有什么帮助吗?

我试图获得的视觉方式:

  1. 用户在移动应用程序中按“使用 Facebook 登录”
  2. 移动应用程序调用 /api/auth/login-facebook/ 传递来自 Facebook 的 access-token
  3. 在 API 应用程序中,我将使用 Facebook 包检查 access-token
  4. 如果用户不存在,我将使用 Facebook 返回给我的数据创建他,之后我将生成 access-token 以授予对我的 API 应用程序的访问权限
  5. 如果用户存在,我将生成 access-token 以授予对我的 API 应用程序的访问权限
  6. access-token 返回给移动应用程序,以便它可以调用其他服务

如果我的知识有误,我应该以其他方式进行集成/登录,请随时告诉我!

最佳答案

您描述的流程与“断言授权”非常相似,该流程是 standardized去年。

要使用此流程,您通常必须从外部提供程序(例如 JWT 或 SAML 断言)检索标准 token ,以便您自己的授权服务器可以 validate it并提取它公开的声明。不幸的是,这不是您可以通过 Facebook 或一般的大多数社交提供商来做的事情。

A new OAuth2 draft将来可能会帮助改变这种情况,但主要服务开始实现它可能需要一段时间。

好消息是,您可以同时创建自己的“Facebook 访问 token ”授权类型。以下是使用 ASOS beta6 实现断言授权的方法:

public override Task ValidateTokenRequest(ValidateTokenRequestContext context)
{
    // Reject the token request if it doesn't use grant_type=password, refresh_token
    // or urn:ietf:params:oauth:grant-type:facebook_access_token.
    if (!context.Request.IsPasswordGrantType() &&
        !context.Request.IsRefreshTokenGrantType() &&
         context.Request.GrantType != "urn:ietf:params:oauth:grant-type:facebook_access_token")
    {
        context.Reject(
            error: OpenIdConnectConstants.Errors.UnsupportedGrantType,
            description: "The specified grant type is not supported by this server.");

        return Task.FromResult(0);
    }

    // Reject the token request if the assertion parameter is missing.
    if (context.Request.GrantType == "urn:ietf:params:oauth:grant-type:facebook_access_token" &&
        string.IsNullOrEmpty(context.Request.Assertion))
    {
        context.Reject(
            error: OpenIdConnectConstants.Errors.InvalidRequest,
            description: "The assertion is missing.");

        return Task.FromResult(0);
    }

    // Since there's only one application and since it's a public client
    // (i.e a client that cannot keep its credentials private), call Skip()
    // to inform the server the request should be accepted without 
    // enforcing client authentication.
    context.Skip();

    return Task.FromResult(0);
}

public override Task HandleTokenRequest(HandleTokenRequestContext context)
{
    // Only handle grant_type=password and urn:ietf:params:oauth:grant-type:facebook_access_token
    // requests and let the OpenID Connect server middleware handle the refresh token requests.
    if (context.Request.IsPasswordGrantType())
    {
        // Skipped for brevity.
    }

    else if (context.Request.GrantType == "urn:ietf:params:oauth:grant-type:facebook_access_token")
    {
        // The assertion corresponds to the Facebook access token.
        var assertion = context.Request.Assertion;

        // Create a new ClaimsIdentity containing the claims that
        // will be used to create an id_token and/or an access token.
        var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);

        // Validate the access token using Facebook's token validation
        // endpoint and add the user claims you retrieved here.
        identity.AddClaim(ClaimTypes.NameIdentifier, "FB user identifier");

        // Create a new authentication ticket holding the user identity.
        var ticket = new AuthenticationTicket(
            new ClaimsPrincipal(identity),
            new AuthenticationProperties(),
            OpenIdConnectServerDefaults.AuthenticationScheme);

        // Set the list of scopes granted to the client application.
        ticket.SetScopes(new[]
        {
            /* openid: */ OpenIdConnectConstants.Scopes.OpenId,
            /* email: */ OpenIdConnectConstants.Scopes.Email,
            /* profile: */ OpenIdConnectConstants.Scopes.Profile,
            /* offline_access: */ OpenIdConnectConstants.Scopes.OfflineAccess
        }.Intersect(context.Request.GetScopes()));

        context.Validate(ticket);
    }

    return Task.FromResult(0);
}

enter image description here

关于c# - 使用 OpenIdConnectServer 并尝试通过 API 服务连接到 Facebook,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39008642/

相关文章:

c# - 如何在 C# 中以编程方式更改 HTML 文件的 CSS 链接?

c# - 创建一个set get类并在构造函数中传递参数

ios - 为什么显示 "ld: framework not found Bolts"

c# - 如何在不知道构建配置的情况下将 EXE 从 .net 核心应用程序的 bin 目录复制到 wwwroot?

c# - 访问 ASP.NET Core 中的配置选项 : options pattern

c# - 为什么结构允许接口(interface)继承,为什么类不能继承

c# - 如何在 WPF 中更改 ViewPort3D 背景颜色?

ios - 在 ComponentKit 中播放视频

ios - 如何将通过 facebook 注册的用户与使用同一电子邮件注册的现有用户合并

Azure,MVC Core Web App突然抛出 "XmlException: Root element is missing"+ "CryptographicException"