如何在使用ResourceOwnerPassword授予类型

时间:2017-11-09 09:51:59

标签: c# oauth .net-core identityserver4

一些背景信息:我正在将我们的Oauth服务器升级到身份服务器。我们正在使用IdentityServer4。

由于向后兼容性,我需要创建一个类似服务帐户的东西,这样我就可以冒充用户了。我认为我所追求的是类似于Twitter Oauth1类型的客户端。我一直在尝试使用GrantTypes.ResorceOwerPassword

客户:

 new Client
                {
                    ClientId = "ServiceAccountAccess",
                    // no interactive user, use the clientid/secret for authentication
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                    // secret for authentication
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    // scopes that client has access to
                    AllowedScopes =
                    {
                        "api.full_access"
                    },
                    AlwaysIncludeUserClaimsInIdToken = true
                }

我的用户:

 new TestUser
            {
                SubjectId = "1",
                Username = "alice",
                Password = "password",
                Claims = new []
                {
                new Claim("name", "Alice"),
                new Claim("website", "https://alice.com")
            }
            },

用法:

var tokenClient = new TokenClient(disco.TokenEndpoint, "ServiceAccountAccess", "secret");
      var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("alice", "password", "api.full_access");

现在这确实有效我可以登录。然而,我遇到的问题是我无法看到这是爱丽丝。我试图做一个用户信息。

UserInfo调用

  // Get UserInfo
  var client = new HttpClient();
  client.SetBearerToken(tokenResponse.AccessToken);
  var response = await client.GetAsync(disco.UserInfoEndpoint);
  if (!response.IsSuccessStatusCode)
  {
    Console.WriteLine(response.StatusCode);
  }
  else
  {
    var content = await response.Content.ReadAsStringAsync();
    Console.WriteLine(JArray.Parse(content));
  }

结果:

这是以“未经授权禁止”

返回

我需要知道这个用户是谁。

1 个答案:

答案 0 :(得分:2)

问题是为了访问包含配置文件和openid范围所需的用户信息

客户:

 new Client
                {
                    ClientId = "ServiceAccountAccess",
                    // no interactive user, use the clientid/secret for authentication
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                    // secret for authentication
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    // scopes that client has access to
                    AllowedScopes =
                    {
                        "api.full_access" ,
                         IdentityServerConstants.StandardScopes.OpenId,
                         IdentityServerConstants.StandardScopes.Profile
                    },
                    AlwaysIncludeUserClaimsInIdToken = true
                }

用法:

var tokenClient = new TokenClient(disco.TokenEndpoint, "ServiceAccountAccess", "secret");
      var tokenResponse = await tokenClient.RequestResourceOwnerPasswordAsync("alice", "password", "api.full_access profile openid");

UserInfo调用

  // Get UserInfo
  var client = new HttpClient();
  client.SetBearerToken(tokenResponse.AccessToken);
  var response = await client.GetAsync(disco.UserInfoEndpoint);
  if (!response.IsSuccessStatusCode)
  {
    Console.WriteLine(response.StatusCode);
  }
  else
  {
    var content = await response.Content.ReadAsStringAsync();
    Console.WriteLine(JArray.Parse(content));
  }

结果:

{"name":"Alice","website":"https://alice.com","sub":"1"}

更新

我刚在文档中找到了这个

  

访问令牌现在将包含唯一的子声明   识别用户。通过检查可以看出这个“子”主张   调用API后的内容变量也将显示   在控制台应用程序的屏幕上。

这意味着我不需要从userinfo请求主题ID在返回的访问令牌中的声明中