## Opsætning af HTTP-klient

S2S (System-to-System) platformen har gennemgået en modernisering og er gået fra SOAP webservices til en HTTP API som bruger XML. Denne opgradering kræver, at alle integrerende parter migrerer deres eksisterende SOAP-forbindelser til korrekt konfigurerede HTTP-klienter.

Denne vejledning giver et komplet overblik over:

- Detaljer om HTTP XML API’en

- Krævede konfigurationsændringer for klientintegration

- Autentificerings- og sikkerhedskrav (mTLS med OCES-certifikater)

- Struktur for API-endpoints

- Implementering af digitale signaturer på XML payloads

Gennem denne dokumentation finder du Java-kodeeksempler fra referenceklienten. Disse eksempler viser kodeudsnit, der kan bruges som reference til din egen implementering.

### Endpoints

Endpoint-stierne er struktureret på en måde, der bevarer navngivningen fra SOAP-endpoints. Hver SOAP-action har sin egen unikke URL-mapping.

Alle endpoints følger mønsteret:

    xml-api.tinglysning.dk/<SOAP_WEB_SERVICE_NAME>/<SOAP_ACTION>

Eksempler på endpoints er vist nedenfor:

SOAP Web Service | SOAP Action | Endpoint URL
--- | --- | ---
ElektroniskAkt | BilSummariskHent | xml-api.tinglysning.dk/ElektroniskAkt/BilSummariskHent
TingbogAnmeld | EjendomOpret | xml-api.tinglysning.dk/TingbogAnmeld/EjendomOpret
Abonnement | AbonnementOpret | xml-api.tinglysning.dk/Abonnement/AbonnementOpret

### OCES-certifikat

Alle endpoints kræver mTLS, hvor klienten bruger et gyldigt OCES-certifikat.

Hvis der ikke bruges et gyldigt OCES-certifikat til mTLS, vil endpoints svare med HTTP-status `400 Bad Request` og en fejlmeddelelse i XML der følger skemaet definiret i Fejl.xsd.

I tilfælde af manglende OCES-certificering vil fejlen i XML se sådan ud:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">
        <faultcode>Client</faultcode>
        <faultstring>Der var intet SSL certifikat i requestet</faultstring>
    </Fejl>

### Referenceimplementering

Referenceklienten i Java viser, hvordan man opretter en `SSLContext` med et OCES-klientcertifikat og en OCES truststore.

Dette kan derefter bruges til at opsætte en HTTP-klient.

Som vist i Java referenceklienten kan en `SSLContext` oprettes ved at:

    1
    Unresolved directive in klient.adoc - include::{javaDir}/SslContextCreate.java[]

En HTTP-klient kan derefter oprettes og konfigureres med mTLS:

    1
    Unresolved directive in klient.adoc - include::{javaDir}/HttpClientCreate.java[]

### Verificering

Java referenceklienten leveres med forbindelsestests. De bruges til at sikre, at det er muligt at oprette forbindelse til e-Tinglysning. For at verificere, at OCES-certifikaterne er korrekte, skal du opdatere application.properties-filen i integrationstestpakken. Derefter kan du køre en af integrationstestene (for eksempel ElektroniskAktSpec). Alternativt kan du køre `gradle integrationTest` for at køre alle forbindelsestests.

Eksempel på konfiguration af keystores vises nedenfor:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    ssl.keystore.system.certificate.path=test.pfx
    ssl.keystore.system.certificate.password=Test1234
    ssl.keystore.system.certificate.key.alias=testSystem
    ssl.keystore.system.certificate.type=PKCS12

    ssl.truststore.path=test.p12
    ssl.truststore.password=Test1234
    ssl.truststore.type=PKCS12

    ssl.keystore.company.certificate.path=test.pfx
    ssl.keystore.company.certificate.password=Test1234
    ssl.keystore.company.certificate.key.alias=testCompany
    ssl.keystore.company.certificate.type=PKCS12

## Headers

S2S-serveren er konfigureret til at kræve et sæt brugerdefinerede headers i hvert HTTP-kald. For at kunne foretage en succesfuld forespørgsel er du ansvarlig for at konfigurere din HTTP-klient til at sende disse headers med dine kald. Dette kapitel giver et overblik over de forventede værdier og mulige fejl, du kan støde på.

Header | Påkrævet | Format
--- | --- | ---
Tinglysning-Message-ID | Ja | uuid:[uuid-v4]
Tinglysning-Relates-To | Nej | String

### Tinglysning-Message-ID

Tinglysningsbeskedens ID er en tilfældigt genereret UUIDv4, som klienten skaber, inden en ny forespørgsel sendes til S2S-endpointet. Denne header bruges til entydigt at identificere hele request-response processen, og derfor er den påkrævet i alle forespørgsler. Den hjælper også begge parter med lettere fejlfinding.

#### Header-struktur

Headeren består af præfikset "uuid:" efterfulgt af en tilfældigt genereret UUIDv4. Headeren må ikke indeholde store bogstaver.

Header-navn | Header-værdi
--- | ---
Tinglysning-Message-ID | uuid:44b147ff-b221-43f7-be45-cdb55f085413

#### Forventede fejl

Hvis headeren ikke angives, kan du forvente HTTP-status `400 Bad Request` med dette XML-svar:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">
        <ns2:faultcode xmlns="" xmlns:ns2="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">Client</ns2:faultcode>
        <faultstring>Følgende krævede header var ikke tilstede: Tinglysning-Message-ID</faultstring>
    </Fejl>

Hvis headeren har en ugyldig struktur, kan du forvente HTTP-status `400 Bad Request` med dette XML-svar:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">
        <ns2:faultcode xmlns="" xmlns:ns2="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">Client</ns2:faultcode>
        <faultstring>Det modtagne MessageID er i invalidt format: uuid:ce01bb6d-3479-4975-8ab5-. Et MessageID skal være på formen uuid:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}</faultstring>
    </Fejl>

### Tinglysning-Relates-To

Nogle gange har din applikation brug for at inkludere yderligere referenceinformation i kaldet. Du kan benytte "relates to"-headeren til dette formål. Denne header er ikke påkrævet og forventer en strengværdi.

Header-navn | Header-værdi
--- | ---
Tinglysning-Relates-To | CASE-2024-001

### Content-Type

Alle endpoints forventer, at brugeren leverer deres request body i XML-format. API’et er konfigureret til at modtage XML og vil også svare med XML. Hvis headeren udelades, vil den blive udfyldt automatisk, men du kan også selv sætte den.

Header-navn | Header-værdi
--- | ---
Content-Type | application/xml

#### Forventede fejl

Hvis du angiver en anden værdi, vil forespørgslen blive afvist med HTTP-status `415 Unsupported Media Type` og denne besked:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">
        <ns2:faultcode xmlns="" xmlns:ns2="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">Client</ns2:faultcode>
        <faultstring>Ikke understøttet Content-Type: 'test/test'. Indstil venligst 'Content-Type'-headeren til 'application/xml'.</faultstring>
    </Fejl>

#### Referenceimplementering

Givet korrekt SSL-kontekst og HTTP-klientopsætning (se Reference OCES implementering), kan du foretage et succesfuldt kald ved at bruge det angivne eksempel fra Java referenceklienten:

    1
    Unresolved directive in headers.adoc - include::{javaDir}/ExampleRequest.java[]

## Signering af payload

Dette kapitel beskriver, hvordan man digitalt signerer XML-dokumenter ved hjælp af OCES (Offentlige Certifikater til Elektronisk Service) certifikater. Implementeringen understøtter flere signaturtyper til forskellige brugsscenarier i den danske digitale infrastruktur. Signeringen af dokumentet er ens for både SOAP og HTTP.

### Signaturtyper

1. Systemcertifikat-signering

   Bruges til standard dokumentoperationer såsom datahentning og søgning. Dette skal bruges som standard, medmindre andet er angivet.

2. Uigenkaldelighedscertifikat-signering

   Bruges til juridisk bindende dokumenter, der ændrer eksisterende data.

3. Disponentsignering

   Bruges til juridisk bindende dokumenter, hvor en person handler på vegne af en anden person eller virksomhed.

De fleste endpoints kræver stadig, at du signerer dokumentet. Hvis du er i tvivl om, hvilken signaturtype der skal anvendes, så tjek request-meddelelsens XSD i controller-dokumentationen. I de fleste tilfælde vil systemcertifikat-signering være det korrekte valg.

Anvendelse og implementering af signaturtyper kan findes i referenceklienten ved at undersøge følgende metoder:

    1
    Unresolved directive in signing.adoc - include::{javaDir}/SigningMethodsOverview.java[]

### Signaturens indhold

Signaturen består af en krypteret streng, der tilføjes til XML’en, som sendes i request body.

I øjeblikket understøtter S2S-serveren RSA_SHA1, RSA_SHA256 og RSA_SHA512 algoritmer til signaturmetoder samt RSA_SHA1 og RSA_SHA256 til digest. Oprettelse af signaturer med andre algoritmer vil medføre afvisning af dokumentet. Af sikkerhedsmæssige årsager anbefales det at bruge mindst RSA_SHA256, da RSA_SHA1 ikke længere anses for at være sikker.

Alle signaturer følger XML Digital Signature-specifikationen og inkluderer:

- SignedInfo: Indeholder canonicalization-metode, signaturalgoritme og referencer

- KeyInfo: Indlejrer det X.509-certifikat, der er brugt til signering

- Signature Value: Den faktiske kryptografiske signatur

Forskelle mellem signeringsmetoder:

Disponentsignaturer | Basis signaturer
--- | ---
Bruger XPath-filtrering til kun at signere specifikke dele af dokumentet, mens metadata og administrative elementer udelades | Hele dokumentet signeres i et dedikeret element til sidst i XML’en
Bruger CanonicalizationMethod.INCLUSIVE | Bruger CanonicalizationMethod.EXCLUSIVE

For disponentsignaturer vil HTTP XML API kontrollere, at det korrekte XPath-udtryk benyttes. En af følgende udtryk kan bruges til at udelade dele af dokumentet fra signeringen.

XPATH_SUBSET_V1

    Unresolved directive in signing.adoc - include::{javaDir}/XpathSubsetv1.java[]

XPATH_SUBSET_V2

    Unresolved directive in signing.adoc - include::{javaDir}/XpathSubsetv2.java[]

Her er et eksempel fra referenceklienten på, hvordan du kan inkludere XPath i dit projekt:

    1
    Unresolved directive in signing.adoc - include::{javaDir}/XpathInclude.java[]

### Eksempler på anvendelse

Da S2S referenceklienten forventer, at XML’en videregives som en String, vil de nuværende eksempler parse til Document ved hjælp af hjælpefunktioner.

Ved dataudtræk er en simpel signatur tilstrækkelig:

    1
    Unresolved directive in signing.adoc - include::{javaDir}/SignBasic.java[]

Når du skal ændre eller tilføje nye data, skal signering med mulighed for benægtelse anvendes. Eksemplet nedenfor viser et tilfælde, hvor en disponent er involveret i oprettelsen af dokumentet. Dette kræver to typer signaturer på samme tid:

    1
    Unresolved directive in signing.adoc - include::{javaDir}/SignDisponentRepudiation.java[]

## Generel fejlsvar

Generelle fejlsvar består af et HTML-svar med en body, der følger XML Fejl.xsd. Her er resultatet af en eksempel-forespørgsel med ugyldig UUID.

    HTTP/1.1 400 Bad Request
    Date: Thu, 31 Jul 2025 13:43:48 GMT
    Server: Apache/2.4.59 (Win64) OpenSSL/3.1.5
    Access-Control-Allow-Credentials: true
    Referrer-Policy: same-origin
    X-Frame-Options: DENY
    Content-Type: application/xml;charset=UTF-8
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1; mode=block
    Access-Control-Allow-Origin: http://localhost:4200
    Access-Control-Allow-Headers: origin, x-requested-with, content-type
    Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS
    X-Apache-Request-Id: (null)
    X-Apache-Stats: Received: t=1753969428028952 Elapsed time: D=125634
    X-Apache-Node: localhost
    Connection: close
    Transfer-Encoding: chunked
    Content-Length: 432

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?><Fejl xmlns="http://rep.oio.dk/tinglysning.dk/schema/fault/1/"><ns2:faultcode xmlns="" xmlns:ns2="http://rep.oio.dk/tinglysning.dk/schema/fault/1/">Client</ns2:faultcode><faultstring>Det modtagne MessageID er i invalidt format: uuid:44b147ff-b221-43f7-be45-. Et MessageID skal være på formen uuid:[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}</faultstring></Fejl>