IdentityServer4:为Client_Credential Granttype添加自定义默认声明到客户端主体

时间:2017-05-10 13:37:57

标签: asp.net-core asp.net-core-mvc claims-based-identity identityserver4 asp.net-core-identity

我正在使用IdentityServer4,我正在尝试在创建令牌时向我的CLIENT添加自定义默认声明。如果我使用隐式流和IProfileService,如下所示,这是可能的。

public class MyProfileService : IProfileService
{
    public MyProfileService()
    {

    }
    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var claims = new List<Claim>
        {
            new Claim("DemoClaimType", "DemoClaimValue")
        };
        context.IssuedClaims = claims;
        return Task.FromResult(0);
    }
    public Task IsActiveAsync(IsActiveContext context)
    {
        context.IsActive = true;
        return Task.FromResult(0);
    }
}

在我的创业公司

services.AddIdentityServer()
            .AddProfileService<MyProfileService>()

但是,对于client_credential granttype的客户端,这不起作用,因为它似乎cannot request OpenID scopes in client credentials flow。事实证明,Iprofileservice就像名称暗示适用于Identity资源一样,其中OpenId范围如profile是有效的。因为我无法请求具有client_credential授权类型GetProfileDataAsync的配置文件范围,所以永远不会被调用。

由于我只使用客户端而没有用户,我需要一种方法将声明注入令牌而无需将它们添加到客户端对象,如下所示

    new Client
{
    ClientId = "myclient",
    ClientName = "My Client",
    AllowedGrantTypes = GrantTypes.ClientCredentials,
    ClientSecrets = {new Secret("secret".Sha256())},
    AllowedScopes = new List<string> {"api"},                    
    AllowOfflineAccess = true,

    //I Don't want to do this
    Claims = new List<Claim>
    {   
        new Claim("type","value")
    }
}

我不想要上述内容,因为我不希望声明成为数据库中client_claims的一部分。我需要在令牌请求时动态创建它。我希望我的问题现在更清楚了。

2 个答案:

答案 0 :(得分:8)

通过一些询问,我终于找到了如何做到这一点。我需要一种方法在请求令牌时动态地向客户端添加声明。

为了做到这一点,我必须扩展ICustomTokenRequestValidator,然后在Startup.cs中包含我的类彻底的依赖注入

public class DefaultClientClaimsAdder : ICustomTokenRequestValidator
{
    public Task ValidateAsync(CustomTokenRequestValidationContext context)
    {
        context.Result.ValidatedRequest.Client.AlwaysSendClientClaims = true;
        context.Result.ValidatedRequest.ClientClaims.Add(new Claim("testtoken","testbody"))

        return Task.FromResult(0);
    }
}

在Startup.cs中配置服务

 services.AddTransient<ICustomTokenRequestValidator, DefaultClientClaimsAdder>();

答案 1 :(得分:2)

或者,您可以使用ClientStore向客户添加新声明。

public class YourClientStore : IClientStore
{
    private readonly DbContext _context;
    private readonly IMapper _mapper;
    public YourClientStore(DbContext context,
        IMapper mapper)
    {
        _context= context;
        _mapper = mapper;
    }

    public Task<Client> FindClientByIdAsync(string clientId)
    {
        var dbClient = _context.Clients.AsQueryable()
            .Where(x => x.ClientId == clientId)
            .FirstOrDefault();
        var client = _mapper.Map<Client>(dbClient);
        if (client != null)
        {
            client.Claims.Add(new Claim("<your claim name>", "<your claim value>"));
        }
        return Task.FromResult(client);
    }
}