如何通过 ASP.NET Identity的FacebookAuthenticationProvider传递自定义声明?



从Visual Studio的" Web api "开始;项目模板中,我试图将自定义声明添加到由/Api/Account/ExternalLogin端点创建的令牌中。我通过FacebookAuthenticationProvider.OnAuthenticated回调添加这些,但它们不会持续到OAuthAuthorizationServerProvider.AuthorizationEndpointResponse()

注意:我使用的方法与Rahul Nath在他的文章ASP中记录的方法类似。. NET Web API和外部登录-通过社交网络进行身份验证

代码

在我的Startup.Auth.cs类的ConfigureAuth()方法(从OwinStartup类的Configuration()方法调用)中,我向OnAuthenticated属性添加了一个回调函数,以便设置单个声明foo,其值为bar:

var facebookAuthenticationProvider = new FacebookAuthenticationProvider() 
{
    OnAuthenticated = (context) => 
    {
        context.Identity.AddClaim(new Claim("foo", "bar"));
        return Task.FromResult(0);
    }
};

然后将FacebookAuthenticationProvider实例添加到新的FacebookAuthenticationOptions对象:

var facebookAuthenticationOptions = new FacebookAuthenticationOptions() 
{
    AppId = "XXXX",
    AppSecret = "YYYY",
    Provider = facebookAuthenticationProvider
};

传递给OWIN的UseFacebookAuthentication()方法:

app.UseFacebookAuthentication(facebookAuthenticationOptions);
结果

如果我在OnAuthenticated回调中放置一个断点,我可以看到我的自定义声明正在被添加,以及许多其他声明(包括来自urn:facebook命名空间的一对)。到目前为止一切顺利。

当我在Facebook身份验证后通过OAuthAuthorizationServerProvider类的AuthorizationEndpointResponse()方法检查我的声明时,context.Identity.Claims集合中只有两个声明可用:

  • http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
  • http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name

所有的urn:facebook索赔已被删除,我的自定义foo索赔也已删除。我假设管道中的其他位置正在使用一组基本声明重新创建身份,但我不确定在哪里。

想法吗?

我有以下代码来访问自定义声明:

 public class AppUser : ClaimsPrincipal{
    public AppUser(ClaimsPrincipal principal): base(principal){}
    public string Role{
        get{
            return this.FindFirst(ClaimTypes.Role).Value;
        }
    }  
    public string ProfileID{
        get{
            return this.FindFirst("ProfileID").Value;
        }
    }
}

您可能需要编辑ExternalLoginData私有类,以包含您希望通过流传递的附加声明。在默认的VS2013模板类文件中,可以在AccountController.cs文件中找到这个私有类。

我有一个类似的问题,不能从谷歌索赔传递电子邮件,这解决了这个问题(注意添加的" email "变量和引用它在两个方法:

private class ExternalLoginData
{
    public string LoginProvider { get; set; }
    public string ProviderKey { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
    public IList<Claim> GetClaims()
    {
        IList<Claim> claims = new List<Claim>();
        claims.Add(new Claim(ClaimTypes.NameIdentifier, ProviderKey, null, LoginProvider));
        if (UserName != null)
        {
            claims.Add(new Claim(ClaimTypes.Name, UserName, null, LoginProvider));
        }
        if (Email != null)
        {
            claims.Add(new Claim(ClaimTypes.Email, Email, null, LoginProvider));
        }
        return claims;
    }
    public static ExternalLoginData FromIdentity(ClaimsIdentity identity)
    {
        if (identity == null)
        {
            return null;
        }
        Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
        if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer)
            || String.IsNullOrEmpty(providerKeyClaim.Value))
        {
            return null;
        }
        if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer)
        {
            return null;
        }
        return new ExternalLoginData
        {
            LoginProvider = providerKeyClaim.Issuer,
            ProviderKey = providerKeyClaim.Value,
            UserName = identity.FindFirstValue(ClaimTypes.Name),
            Email = identity.FindFirstValue(ClaimTypes.Email)
        };
    }
}

相关内容

  • 没有找到相关文章

最新更新