Claims providers
You can add your custom claims providers to the server. The ProfileService
uses claims providers defined in resources properties.
When a client asks for a resource (Identity or API), the ProfileService
looks for the ClaimProviderType key in its properties. If found, the dependency injection container is searched for this type's full name in the IProvideClaims
collection and calls the method ProvideClaims
with the current context subject, client, caller, and properties.
If the provider is not found in the DI container and the property ClaimProviderAssemblyPath exists, it loads the assembly from this path and creates an instance of the provided type.
Implement
Claims providers must implement the IProvideClaims
interface.
sample
The project sample/Aguacongas.TheIdServer.CustomClaimsProvider contains an implementation sample.
public class MapClaimsProvider: IProvideClaims
{
public Task<IEnumerable<Claim>> ProvideClaims(ClaimsPrincipal subject, Client client, string caller, Resource resource)
{
var defaultOutboundClaimMap = JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap;
var claims = new List<Claim>(subject.Claims.Count());
foreach (var claim in subject.Claims)
{
if (defaultOutboundClaimMap.TryGetValue(claim.Type, out string toClaimType))
{
claims.Add(new Claim(toClaimType, claim.Value, claim.ValueType, claim.Issuer));
}
}
return Task.FromResult(claims as IEnumerable<Claim>);
}
}
If your provider has dependencies, you can register it in the dependencies injection container by implementing the ISetupClaimsProvider
interface.
sample
The project sample/Aguacongas.TheIdServer.CustomClaimsProvider contains an implementation sample.
public class ClaimsProvidersSetup : ISetupClaimsProvider
{
public IServiceCollection SetupClaimsProvider(IServiceCollection services, IConfiguration configuration)
{
services.AddHttpClient("claims")
.ConfigureHttpClient(client => client.BaseAddress = new Uri(configuration.GetValue<string>("ClaimsWebServiceUrl")));
return services.AddTransient<IProvideClaims>(p => new WebServiceClaimsProvider(p.GetRequiredService<IHttpClientFactory>().CreateClient("claims")));
}
}
To avoid
TypeLoadException
copy Aguacongas.IdentityServer.Duende.dll or Aguacongas.IdentityServer.IS4.dll from your TheIdServer installation folder and reference it in your project:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <Reference Include="Aguacongas.IdentityServer.Duende"> <HintPath>Aguacongas.IdentityServer.Duende.dll</HintPath> </Reference> </ItemGroup> <ItemGroup> <PackageReference Include="Duende.IdentityServer" Version="6.1.7" /> </ItemGroup> </Project>
Configuration
To register your claims providers in the DI container, add the setup class declaration in the ClaimsProviderOptions configuration section.
"ClaimsProviderOptions": [
{
"AssemblyPath": "{path to dll containing the setup class}",
"TypeName": "{Full name of the setup class}"
}
]
sample
"ClaimsProviderOptions": [
{
"AssemblyPath": "Aguacongas.TheIdServer.CustomClaimsProviders.dll",
"TypeName": "Aguacongas.TheIdServer.CustomClaimsProviders.ClaimsProvidersSetup"
}
]
In a resource (Identity or API) your client asks for, add the property ClaimProviderType with full type name of a class implementing the IProvideClaims
interface.
If you do not register your providers in the DI container, add the path to the assembly containing this class in the property ClaimProviderAssemblyPath.
Public/private scenario
When the server acts as a proxy, the profile service is a ProxyProfileService
instance. This class forwards each request to claims providers to the webservice endpoint /claimsprovider.
This way, you are not required to expose your claims providers to the Internet and don't have to open custom network firewall rules to access private resources (such as DB, private service, etc...) on the public side.
Read Using the API for information on how to configure a public/private cluster.