This is a .NET library for Maskinporten authentication and authorization. There is also a similar version available for Java here
The NuGet package is signed with a KS certificate in our build process, stored securely in a safe build environment. The package assemblies are also strong-named.
Install KS.Fiks.Maskinporten.Client NuGet package in your .NET project.
// For TEST
var maskinportenConfigTest = MaskinportenClientConfigurationFactory.CreateTestConfiguration("test_issuer", testCertificate);
// For PROD
var maskinportenConfigProd = MaskinportenClientConfigurationFactory.CreateProdConfiguration("prod_issuer", certificate);
// DEPRECATED - For TEST (ver2)
var maskinportenConfigVer2 = MaskinportenClientConfigurationFactory.CreateVer2Configuration("ver2_issuer", testCertificate);
var maskinportenConfig = new MaskinportenClientConfiguration(
audience: @"https://test.maskinporten.no/", // Maskinporten audience path
tokenEndpoint: @"https://test.maskinporten.no/token", // Maskinporten token path
issuer: @"issuer", // Issuer name, heter nå Integrasjonens identifikator i selvbetjeningsløsningen til DigDir
numberOfSecondsLeftBeforeExpire: 10, // The token will be refreshed 10 seconds before it expires
certificate: /* virksomhetssertifikat as a X509Certificate2 */,
privateKey: /* use together with public key if not using certificate parameter */,
publicKey: /* use together with private key if not using certificate parameter */,
keyIdentifier: /* optional value. Sets header kid */,
consumerOrg: /* optional value. Sets header consumer_org */);
var maskinportenConfig = new MaskinportenClientConfiguration(
audience: @"https://ver2.maskinporten.no/", // Maskinporten audience path
tokenEndpoint: @"https://ver2.maskinporten.no/token", // Maskinporten token path
issuer: @"issuer", // Issuer name, heter nå Integrasjonens identifikator i selvbetjeningsløsningen til DigDir
numberOfSecondsLeftBeforeExpire: 10, // The token will be refreshed 10 seconds before it expires
certificate: /* virksomhetssertifikat as a X509Certificate2 */,
privateKey: /* use together with public key if not using certificate parameter */,
publicKey: /* use together with private key if not using certificate parameter */,
keyIdentifier: /* optional value. Sets header kid */,
consumerOrg: /* optional value. Sets header consumer_org */);
DigDir maintains a list of well-know endpoints and configuration for the available environments
var maskinportenClient = new MaskinportenClient(maskinportenConfig);
var scope = "ks:fiks"; // Scope for access token
var accessToken = await maskinportenClient.GetAccessToken(scope);
var tokenRequest = new TokenRequestBuilder()
.WithScopes("ks:fiks") // Scope for access token
.WithConsumerOrg("123456789") // Official 9 digit organization number for an organization that has delegated access to you in ALTINN
.WithOnBehalfOf("123456789") // Official 9 digit organization number for an organization that has delegated access to you in ALTINN
.WithAudience("https://some/api") // 'resource' claim in the JWT grant and 'aud' claim in the resulting access token
.WithPid("12345678901") // Personal indentification number of the intended subject of the subsequent API calls
.Build();
var accessToken = await maskinportenClient.GetAccessToken(tokenRequest);
var scope = "ks:fiks"; // Scope for access token
var consumerOrgNo = ...; // Official 9 digit organization number for an organization that has delegated access to you in ALTINN
var accessToken = await maskinportenClient.GetDelegatedAccessToken(consumerOrgNo, scope);
For more information on this feature, check the delegation documentation at DigDir
var audience = "https://some/api"; // Audience for access token
var scope = "ks:fiks"; // Scope for access token
var consumerOrgNo = ...; // Official 9 digit organization number for an organization that has delegated access to you in ALTINN
var accessToken = await maskinportenClient.GetDelegatedAccessTokenForAudience(consumerOrgNo, audience, scope);
For more information on this feature, check the delegation documentation audience-restricted tokens at DigDir
This is a feature with limited usecase
var scope = "ks:fiks"; // Scope for access token
var consumerOrgNo = ...; // Official 9 digit organization number for an organization that has delegated access to you in ALTINN
var accessToken = await maskinportenClient.GetOnBehalfOfAccessToken(consumerOrgNo, scope);
For more information on this feature, check the onbehalfof documentation at DigDir
Please note that as stated in the documentation at DigDir, "Det gir ingen mening å bruke onbehalfof for Maskinporten-integrasjoner", means that for most cases it is not usable and is planned for removal. When it is removed this feature will be removed from this client too.
var httpClient = new HttpClient();
using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, /* api uri */))
{
// Set authorization header with maskinporten access token
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Token);
/* Set other headers. Integration id and password etc.*/
// Send message
var response = await httpClient.SendAsync(requestMessage);
/* Handle response */
}