【问题标题】:Adding custom Claim for access in API with IdentityServer4使用 IdentityServer4 在 API 中添加自定义声明以进行访问
【发布时间】:2018-03-09 12:11:45
【问题描述】:

我正在尝试使用一个应用程序来使用 IdentityServer4,它具有身份服务器、MVC 客户端和 Web API 的基本设置。

我有一个自定义配置文件服务(我已在 Startup.cs 中注册),我正在其中添加自定义声明,这是我的 GetProfileDataAsync 方法:

public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
    var user = _userManager.GetUserAsync(context.Subject).Result;

    var claims = new List<Claim>
    {
        new Claim("TestFullName", user.FullName),
    };

    context.IssuedClaims.AddRange(claims);          

    return Task.FromResult(0);
}

我的问题是,当我登录身份服务器时,我可以看到附加声明 - 但是当我从 MVC 应用程序调用我的 API 时,我的自定义声明不存在。这是我的 MVC 应用程序中调用 API 的代码:

public async Task<IActionResult> ClientAuthorizedAPICall(string token)
{
    // discover endpoints from metadata
    var disco = await DiscoveryClient.GetAsync("http://localhost:5000");

    // request token
    var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
    var tokenResponse = await tokenClient.RequestClientCredentialsAsync("testAPI");        

    // call api
    var client = new HttpClient();
    client.SetBearerToken(tokenResponse.AccessToken);

    var response = await client.GetAsync("http://localhost:5001/identity");
    ...
} 

我的 API 上的方法很简单:

[HttpGet]
public IActionResult Get()
{
    return new JsonResult(from c in User.Claims select new { c.Type, c.Value });           
}

我做错了吗?或者我应该做一些不同的事情而不是使用User.Claims?

【问题讨论】:

  • 如果你在GetProfileDataAsync() 中放置一个断点,它会被调用吗?
  • @Peter - 是的,我登录时添加了声明
  • 因此您正在登录您的 MVC 应用程序(通过 IdentityServer),并且您在 MVC 应用程序中的用户拥有声明并且一切正常。但是看起来您在该 MVC 应用程序中有一个操作,该操作使用客户端凭据获取访问令牌以调用 API 端点......您想知道为什么 API 中不提供该声明?
  • 是的,没错
  • 当用户登录 MVC 应用程序时,您需要发送从身份服务器接收到的访问令牌。从客户端凭据流接收的访问令牌无法知道用户是谁。

标签: c# asp.net-core asp.net-identity openid-connect identityserver4


【解决方案1】:

就像 rawel 的评论所说,您需要使用 MVC 应用用户的访问令牌来进行 API 调用。它看起来像这样:

// get the current user's access token
var accessToken = await HttpContext.GetTokenAsync("access_token");

// call api
var client = new HttpClient();
client.SetBearerToken(accessToken);

var response = await client.GetAsync("http://localhost:5001/identity");

您可以在quickstart on hybrid flow 中看到类似的方法。

要将您的自定义用户声明添加到您的 API 的访问令牌中,您需要在定义 API 资源时包含它。例如:

new ApiResource("testAPI", "Test API", new[] { "TestFullName" }),

【讨论】:

  • 感谢@Peter,这确实有效。我不知道为什么,但是使用你的方法来获取访问令牌,但我的没有,即使他们都给了我相同的访问令牌。知道为什么会这样吗?
  • 这很奇怪 - 我不希望客户端凭据访问令牌与用户的访问令牌相同。客户端凭据令牌不应包含任何用户/身份声明。
  • 那么如何向令牌添加自定义声明?
猜你喜欢
  • 2017-11-29
  • 1970-01-01
  • 2019-01-08
  • 2020-01-15
  • 2021-12-01
  • 2020-02-10
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
相关资源
最近更新 更多