web-dev-qa-db-ja.com

IdentityServer4:Client_CredentialGranttypeのクライアントプリンシパルにカスタムデフォルトクレームを追加

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>()

ただし、これはcannot request OpenID scopes in client credentials flowのように見えるため、client_credentialgranttypeを使用するクライアントでは機能しません。名前が示すようにIprofileserviceは、profileなどのOpenIdスコープが有効なIdentityリソースで機能することがわかりました。 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の一部にしたくないので、上記は必要ありません。トークンリクエストでオンザフライで作成する必要があります。私の質問がより明確になったことを願っています。

9
flexxxit

いくつかの問い合わせで、私はついにこれを行う方法を見つけました。トークンが要求されたときにクライアントにクレームを動的に追加する方法が必要でした。

そのためには、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>();
10
flexxxit

または、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);
    }
}
2
adem caglin