代码之家  ›  专栏  ›  技术社区  ›  johnny 5

.Net核心OAuth嵌套声明未映射回用户

  •  1
  • johnny 5  · 技术社区  · 7 年前

    我试图在OAuth之后获得索赔:

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = COINBASE_AUTH_ID;
    })
    .AddCookie()
    .AddOAuth(COINBASE_AUTH_ID, options =>
    {
        options.ClientId = Configuration["Coinbase:ClientId"];
        options.ClientSecret = Configuration["Coinbase:ClientSecret"];
        options.CallbackPath = new PathString("/signin-coinbase");
    
        options.AuthorizationEndpoint = "https://www.coinbase.com/oauth/authorize";
        options.TokenEndpoint = "https://api.coinbase.com/oauth/token";
        options.UserInformationEndpoint = "https://api.coinbase.com/v2/user";
    
        options.SaveTokens = true;
    
        options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
        options.ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
        options.ClaimActions.MapJsonKey("urn:coinbase:avatar", "avatar_url");
    
        options.Events = new OAuthEvents
        {
            OnCreatingTicket = async context =>
            {
                var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
                request.Headers.Add("CB-VERSION", DateTime.Now.ToShortDateString()); 
                var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
                response.EnsureSuccessStatusCode();
    
                var user = JObject.Parse(await response.Content.ReadAsStringAsync());
    
                context.RunClaimActions(user);
            }
        };
    });
    

    context.RunClaimActions(user) 这应该将我在选项中设置的声明映射到我的用户。

    public class IndexModel : PageModel
    {
        public string CoinbaseId { get; set; }
    
        public string CoinbaseAvatar { get; set; }
    
        public string CoinbaseName { get; set; }
    
        public async Task OnGetAsync()
        {
            if (User.Identity.IsAuthenticated)
            {
                CoinbaseName = User.FindFirst(c => c.Type == ClaimTypes.Name)?.Value;
                CoinbaseId = User.FindFirst(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
                CoinbaseAvatar = User.FindFirst(c => c.Type == "urn:coinbase:avatar")?.Value;
    
            }
        }
    

    但是模型返回所有空值。我从coinbase得到的回复包含了所有3个声明,但是它们似乎没有映射到我的内存用户,有人知道为什么吗?

    编辑

    结果Coinbase没有直接返回user对象,而是返回包装在名为Data的对象中的用户对象。

    options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "data.id"); 
    

    我想我需要手动解析数据对象

    1 回复  |  直到 7 年前
        1
  •  1
  •   johnny 5    7 年前

    为了解决这个问题,我在JObject中用 SelectToken

    var userData = JObject.Parse(await response.Content.ReadAsStringAsync());
    var user = userData["data"];
    
    context.RunClaimActions(JObject.FromObject(user));