标识服务器4 令牌中的所有客户端作用域



我有一个使用IdentityServer4实现保护的多租户应用程序。 我最近将其更新为最新的ID4,行为似乎已更改。 以前,我可以使用 IdentityModel 包中的 TokenClient 发出请求:

var parameters = new Dictionary<string, string>();
parameters.Add("username", loginModel.UserName);
parameters.Add("password", loginModel.Password);
var tokenClient = new TokenClient(new Uri(new Uri(accountsConfig.EndpointUrl), "/connect/token").ToString(), accountsConfig.ClientId, accountsConfig.Secret,  null, AuthenticationStyle.PostValues); 
var tokenResponse = await tokenClient.RequestCustomGrantAsync("AgentLogin", extra: parameters);

它将返回令牌中为客户端定义的所有范围。 现在情况已经不同了。 如何配置 ID4 以执行此操作,而无需在令牌客户端中显式请求它们?

public class AgentLoginCustomGrantValidator : IExtensionGrantValidator
    {
        private readonly ILogger<AgentLoginCustomGrantValidator> _logger;
        private readonly IAdminUserService _adminUserService;
        public AgentLoginCustomGrantValidator(ILogger<AgentLoginCustomGrantValidator> logger, IAdminUserService adminUserService)
        {
            _logger = logger;
            _adminUserService = adminUserService;
        }
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            try
            {
                var username = context.Request.Raw.Get("username");
                var password = context.Request.Raw.Get("password");
                var userId = _adminUserService.AuthenticateUser(username, password);

                if (userId != null)
                {
                    var agencyUser = _adminUserService.GetUser(userId.Value);
                    context.Result = new GrantValidationResult($"{userId}", GrantType, agencyUser.Roles.Select(x => new Claim(JwtClaimTypes.Role, x.Name)).Concat(new List<Claim>() { new Claim(JwtClaimTypes.Name, agencyUser.UserName) { } }));
                }
                else
                {
                    _logger.LogWarning($"Bum creds: {username} ");
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidClient, "Invalid credentials");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidClient, ex.Message);
            }
        }
        public string GrantType => "AgentLogin";
    }
默认情况下,

身份服务器 4 仅返回每个客户端的请求身份或 API 资源。但是,可以轻松重写此行为以返回所有范围,无论它们是否在令牌请求中请求。您可以创建继承自DefaultClaimsServiceCustomClaimsService

public class CustomClaimsService : DefaultClaimsService
{
    public CustomClaimsService(IProfileService profile, ILogger<DefaultClaimsService> logger) : base(profile, logger)
    {
    }
    public override async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject,
        Resources resources, ValidatedRequest request)
    {
        var baseResult = await base.GetAccessTokenClaimsAsync(subject, resources, request);
        var outputClaims = baseResult.ToList();
        //If there are any allowed scope claims that are not yet in the output claims - add them
        foreach (var allowedClientScope in request.Client.AllowedScopes)
        {
            if (!outputClaims.Any(x => x.Type == JwtClaimTypes.Scope && x.Value == allowedClientScope))
            {
                outputClaims.Add(new Claim(JwtClaimTypes.Scope, allowedClientScope));
            }
        }
        return outputClaims;
    }
}

然后只需将其注册到IdentityServerBuilder服务容器即可。

        var builder = services.AddIdentityServer(options =>
        {
            //Your identity server options
        });
        //Register the custom claims service with the service container
        builder.Services.AddTransient<IClaimsService, CustomClaimsService>();

现在,每个访问令牌将包含给定客户端允许的所有范围。

相关内容

  • 没有找到相关文章

最新更新