Selvbetjening API

Dette er teknisk dokumentasjon for bruk av Selvbetjening API ment for utviklere.

API-et lar dere opprette single-tenant-klienter fra en klientmal og gjøre endringer på alle typer klienter, slik som å rotere klientnøkler.

Oversikt over alle endepunkter finner du her

Opprettelse av klient

    sequenceDiagram
    accTitle: Diagram som viser hvordan man kan automatisere klientopprettelse med API-et

    actor EndUser as End User
    participant ClientSystem as Client System
    participant API as api.selvbetjening.nhn.no
    participant Portal as selvbetjening.nhn.no
    participant HelseId as helseid-sts.nhn.no

    ClientSystem ->> API: client draft (using api key) [1]
    activate API
    API -->> ClientSystem: client id
    deactivate API
    ClientSystem ->> Portal: Open URL in browser [2]
    activate Portal
    Portal ->> EndUser: Request confirmation
    EndUser ->> Portal: Confirmation [3]
    Portal ->> ClientSystem: Redirect with status [4]
    deactivate Portal
    ClientSystem ->> HelseId: Request access token for Selvbetjening API (using client id and key) [5]
    activate HelseId
    HelseId -->> ClientSystem: access token
    deactivate HelseId
    ClientSystem ->> API: Get status (using access token) [6]
    activate API
    API -->> ClientSystem: Status
    deactivate API
  1. Opprett en klientkladd via API-et
  2. Send sluttbrukeren til bekreftelsessiden på selvbetjening.nhn.no i en nettleser
  3. Sluttbrukeren bekrefter klienten
  4. Nettleseren omdirigerer brukeren til deres lokale http-server
  5. Ved en vellykket status kan klienten brukes for å forespørre access tokens fra HelseID
  6. Sjekk statusen til klienten sine scope-tilganger

En eksempelimplementasjon i C# finner du på GitHub

Opprettelse av klientkladd

For å opprette klientkladder trengs en API-nøkkel som genereres fra fanen "automatisering" på klientmal-siden.

API-nøkkelen kan distribueres sammen med systeminstallasjonene, og brukes kun for å opprette klientkladder. Etter at HelseID-klienten er opprettet fra kladden, så må systemet bruke denne klienten for videre API-kall.

Generer et nøkkelpar og POST til endepunktet /client-drafts med API-nøkkelen i en header for å opprette klientkladden:

POST /v1/client-drafts HTTP/1.1
Host: api.selvbetjening.nhn.no
Api-Key: D-J1mmTqICvFRK3sgBZVKCqcBXq6NFhSZPjgPOgCxO8
Content-Type: application/json
Accept: application/json

{
    "organizationNumber": "942110464",
    "apiScopes": [
        "nhn:selvbetjening/client",
        "nhn:kjernejournal/api"
    ],
    "publicJwk": "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"fHKI4bI_4yG1x7wfSbcS33N0NWDz0lkSELN1LTaVxtE\",\"y\":\"4JKkagfmenlwCqhhQzir2n_5vn4HmULwLc3bQCJBS60\",\"kid\":\"M2WOBEsDcuWbHUAewajNnMgb-qElkpRhcvBZj6mlmnE\",\"use\":\"sig\",\"alg\":\"ES512\"}",
    "postClientConfirmationRedirectUri": "http://localhost:8080/client-confirm"
}
// KeyGenerator from https://github.com/NorskHelsenett/Selvbetjening.Samples
var jwk = KeyGenerator.GenerateRsaJwk();

// Save jwk.PublicAndPrivateValue to a secure location,
// such as a key vault

var clientDraft = new {
    OrganizationNumber = "942110464",
    PublicJwk = jwk.PublicValue,
    ApiScopes = new []{"nhn:selvbetjening/client", "nhn:kjernejournal/api"},
    PostClientConfirmationRedirectUri = "http://localhost:8080/client-confirm"
};

var client = new HttpClient();
client.DefaultRequestHeaders.Add(
    "Api-Key",
    "D-J1mmTqICvFRK3sgBZVKCqcBXq6NFhSZPjgPOgCxO8"
);

var response = await client.PostAsJsonAsync(
    "https://api.selvbetjening.test.nhn.no/v1/client-drafts",
    clientDraft
);

var body = await response.Content.ReadFromJsonAsync<ResponseModel>();
var clientId = body.ClientId;

record ResponseModel(string ClientId);

En vellyket forespørsel vil få klient-id for den nye klientkladden i responsen:

{
    "clientId": "4095f02f-008e-4413-98ef-5c040eb28b29"
}

Bekreftelse

Klienten må bekreftes av en sluttbruker som representerer virksomheten spesifisert i kladden. Dette gjøres ved å åpne en URL til Selvbetjening i en nettleser hvor brukeren vil logge inn og bekrefte klienten.

info
For å kunne bekrefte klienten, må brukeren enten ha en nødvendig rolle, som f.eks. daglig leder, eller få delegert en rettighet i Altinn. For et strømlinjeformet oppsett, så anbefales det at rettigheten delegeres på forhånd. Denne lenken kan brukes for å be om den nødvendige delegeringen fra virksomheten.

Klientsystemet må lytte på forespørsler til postClientConfirmationRedirectUri (angitt i klientkladden), som Selvbetjening omdirigerer til etter at brukeren har bekreftet klienten.

Klientsystemet må så åpne Selvbetjening i en nettleser med følgende URL-mal: https://selvbetjening(.test).nhn.no/confirm-client/{clientId}.

Når klienten har blitt bekreftet, vil klientsystemet motta en omdirigering til postClientConfirmationRedirectUri med query parameteret status. Se beskrivelsen av postClientConfirmationRedirectUri for mulige statuser.

var confirmationUri = "https://selvbetjening.nhn.no/confirm-client/4095f02f-008e-4413-98ef-5c040eb28b29";
var postClientConfirmationRedirectUri = "http://localhost:8080/client-confirm";

// Open confirmation URI in browser and listen for the confirmation redirect
var browserOptions = new BrowserOptions(
    startUrl: confirmationUri, 
    endUrl: postClientConfirmationRedirectUri
);

// SystemBrowserRunner from https://github.com/NorskHelsenett/Selvbetjening.Samples
using var browserRunner = new SystemBrowserRunner(
    htmlTitle: "My Application",
    htmlBody: "Return to your application"
);
var result = await browserRunner.InvokeAsync(browserOptions, default);

var queryString = result.Response;
var confirmationParameters = HttpUtility.ParseQueryString(queryString);

var isSuccess = confirmationParameters["status"] == "Success";

Ved en vellykket bekreftelse er klienten klar til bruk etter 20 sekunder (HelseID sin cache må oppdateres).

info
URL-en må åpnes innen 10 sekunder etter at klientkladden er opprettet, og kan kun aksesseres fra samme nettleser etter at den først er åpnet. Brukeren må bekrefte klienten innen 3 timer etter åpning av URL-en. Disse er tiltak for å mitigere phishing-angrep.

Sjekke status på tilganger

Sjekk statusen på scope-tilganger ved å bruke endepunktet /client .

Dette endepunktet krever at den opprettede klienten ber om et HelseID access token med scope nhn:selvbetjening/client. Se implementasjonsguiden for klienter for hvordan du integrerer med HelseID.

GET /v1/client/ HTTP/1.1
Host: api.selvbetjening.nhn.no
Authorization: DPoP <access_token>
DPoP: <dpop_proof>
Accept: application/json
var requestMessage = new HttpRequestMessage(
    HttpMethod.Get,
    "https://api.selvbetjening.test.nhn.no/v1/client/"
);

// See the full sample for how to get access token and DPoP proof:
// https://github.com/NorskHelsenett/Selvbetjening.Samples
requestMessage.Headers.Authorization = new("DPoP", "<your_access_token>");
requestMessage.Headers.Add("DPoP", "<your_dpop_proof>");

using var client = new HttpClient();
var response = await client.SendAsync(requestMessage);

var responseData = await response.Content.ReadFromJsonAsync<ResponseModel>();
var scopesAllOk = responseData!.ApiScopes.All(s => s.Status == "ok");

// See endpoint docs for all properties
record ResponseModel(ApiScope[] ApiScopes);
record ApiScope(string Scope, string Status);

Svaret vil inneholde status for hvert API-scope og andre detaljer om klienten:

{
    "apiScopes": [
        {
          "scope": "nhn:selvbetjening/client",
          "status": "ok"
        },
        {
          "scope": "nhn:kjernejournal/api",
          "status": "ok"
        }
    ]
}

Hvis statusen ser bra ut, så er du klar til å hente access tokens for andre API-er.

Nøkkelrotering

Klientnøkler utløper etter 30 dager. Regelmessig nøkkelrotasjon trengs derfor for en fungerende klient.

Roter nøkkelen i god tid før utløp for å unngå avbrudd, f.eks. 15 dager før utløp. Den forrige nøkkelen vil være gyldig i 14 dager etter rotasjonen.

Rotasjonen gjøres med endepunktet /client-secret :

POST /v1/client-secret HTTP/1.1
Host: api.selvbetjening.nhn.no
Authorization: DPoP <access_token>
DPoP: <dpop_proof>
Content-Type: application/json
Accept: application/json

{
    "kty": "EC",
    "crv": "P-256",
    "x": "fHKI4bI_4yG1x7wfSbcS33N0NWDz0lkSELN1LTaVxtE",
    "y": "4JKkagfmenlwCqhhQzir2n_5vn4HmULwLc3bQCJBS60",
    "kid": "M2WOBEsDcuWbHUAewajNnMgb-qElkpRhcvBZj6mlmnE",
    "use": "sig",
    "alg": "ES512"
}
// KeyGenerator from https://github.com/NorskHelsenett/Selvbetjening.Samples
var newJwk = KeyGenerator.GenerateRsaJwk();

// Save jwk.PublicAndPrivateValue to a secure location,
// such as a key vault

var requestMessage = new HttpRequestMessage(
    HttpMethod.Post,
    "https://api.selvbetjening.test.nhn.no/v1/client-secret"
);

// See the full sample for how to get access token and DPoP proof:
// https://github.com/NorskHelsenett/Selvbetjening.Samples
requestMessage.Headers.Authorization = new("DPoP", "<your_access_token>");
requestMessage.Headers.Add("DPoP", "<your_dpop_proof>");

requestMessage.Content = JsonContent.Create(newJwk.PublicValue);

using var client = new HttpClient();
var response = await client.SendAsync(requestMessage);

var responseData = await response.Content.ReadFromJsonAsync<ResponseModel>();
var expiration = responseData.Expiration;

record ResponseModel(DateTime Expiration);

Svaret inneholder utløpsdatoen for den nye nøkkelen:

{
    "expiration": "2025-05-21T00:00:00.00Z"
}

Håndtere utløpte klientnøkler

Hvis en applikasjon ikke er brukt over en lengre periode, vil klientnøkkelen ikke automatisk oppdateres og kan derfor utløpe.

For å håndtere dette, så kan en bruker med tilgang til klienten gjøre følgende:

  1. Generer et nytt nøkkelpar
  2. Logg inn på Selvbetjening og last opp den nye offentlige nøkkelen til klienten
  3. Ta i bruk den nye privatnøkkelen i applikasjonen

Sluttbrukere kan trenge assistanse fra leverandøren for å gjøre denne oppgaven.

Merk: Så lenge applikasjonen brukes gjenvlig, og den offentlige nøkkelen oppdateres, så vil ikke problemet oppstå.