如果用户拒绝范围,则重新请求fb对话 - Identityserver4

时间:2017-10-11 13:55:15

标签: asp.net-core facebook-login identityserver4

Facebook文档提供此javascript代码

FB.login(
  function(response) {
     console.log(response);
},
{
    scope: 'email',
    auth_type: 'rerequest'
});

是否可以在我的StartUp.cs中实现上述功能?

app.UseFacebookAuthentication(new FacebookOptions
{
    AuthenticationScheme = "Facebook",
    DisplayName = "Facebook",
    SignInScheme = 
                IdentityServerConstants.ExternalCookieAuthenticationScheme, 
    AppId = "***",
    AppSecret = "***",

    Events = new OAuthEvents
    {
        OnRemoteFailure = context =>
        {
            context.HandleResponse();
            context.Response.Redirect("/Account/Login");
            return Task.FromResult(0);
        }
     }
});

1 个答案:

答案 0 :(得分:0)

有点晚了,但是我有同样的问题,也许我的解决方案将来会帮助其他人。

首先:要强制在Facebook上显示同意页面,您需要向查询(handling revoked permissions)中添加auth_type=rerequest

第二:单个被撤销的权限不会引发错误。它将以正常方式运行,但没有要求的范围/要求。因此,在这种情况下将不会调用OnRemoteFailureOnRemoteFailure仅在用户完全取消同意页面的情况下才会调用。

现在您可以执行以下操作:

  1. callback method处检查返回的索赔。

  2. 如果缺少电子邮件声明(或其他对您很重要的请求的声明),则将用户重定向到处理此情况的自定义页面。从技术上讲,您可以将用户直接重定向回Facebook,但不建议这样做。 Facebook希望您能向用户确切解释为什么需要所要求的范围(handling revoked permissions)。

  3. 自定义method that initiates the sign-in process,以便您知道何时添加auth_type = request,即步骤2中的用户按下“重试”之类的按钮时。

  4. auth_type=rerequest添加到AuthenticationProperties

        var props = new AuthenticationProperties()
        {
            RedirectUri = Url.Action("ExternalLoginCallback"),
            Items =
                {
                    { "returnUrl", returnUrl },
                    { "scheme", provider },
                    // if user wants to try again
                    { "auth_type", "rerequest" }
                }
        };
        return Challenge(props, provider);
    
  5. 实施OnRedirectToAuthorizationEndpoint来操纵默认的挑战重定向uri

    using Microsoft.AspNetCore.WebUtilities;
    ...
    options.Events = new OAuthEvents
    {
        OnRemoteFailure = ...
        OnRedirectToAuthorizationEndpoint = context =>
        {
            if (context.Properties.Items.ContainsKey("auth_type"))
            {
                context.RedirectUri = QueryHelpers.AddQueryString(context.RedirectUri, "auth_type", context.Properties.Items["auth_type"]);
            }
            context.Response.Redirect(context.RedirectUri);
            return Task.FromResult(0);
        }
    };
    

现在,在需要时会再次显示同意页面。

希望这会有所帮助。