IdentityServer4太多调用会导致性能问题

问题描述 投票:1回答:1

我正在实现一个自定义用户存储,我的用户提供程序位于一个单独的服务中,我正在使用消息传递。

问题是GetProfileDataAsyncIsActiveAsync被调用太多次(每次大约3次),导致每次都启动消息传递过程。

这是一个简单的IProfileService实现。

public class IdentityProfileService : IProfileService
{
    private readonly UserManager<ApplicationUser> _userManager;

    public IdentityProfileService (UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {

        var user = await _userManager.FindBySubjectIdAsync(context.Subject.GetSubjectId());
        if (user != null)
        {
            context.IssuedClaims = user.Claims;
        }
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await _userManager.FindByIdAsync(sub);
        context.IsActive = user != null;
    }
}

我的问题是:

有没有办法减少这些电话的数量?或者我可以检查一些信息,存在意味着没有必要再次调用_userManager.FindBySubjectIdAsync

performance identityserver4
1个回答
3
投票

配置文件服务的调用次数不会太多,但会使用不同的上下文多次调用它:

  • 对于访问令牌Context.Caller = ClaimsProviderAccessToken。
  • 对于身份令牌Context.Caller = UserInfoEndpoint。

每个来电者都期望得到不同的结果。这就是为什么您应该按照请求的声明类型过滤声明:

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
    var sub = context.Subject.GetSubjectId();
    var user = await _userManager.FindByIdAsync(sub);
    var principal = await _claimsFactory.CreateAsync(user);

    var claims = principal.Claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();

    context.IssuedClaims = claims;
}

这就是access_token包含与identity_token不同的声明的原因。

您可以通过不从访问端点请求来自其他端点的信息来最小化呼叫。但您也可以检查呼叫者,并为每个呼叫者采取不同的行动。您还可以为令牌提供更长的生命周期,因此您无需刷新该令牌。

© www.soinside.com 2019 - 2024. All rights reserved.