Skip to content
Snippets Groups Projects
Commit 15715224 authored by David Schwarzmann's avatar David Schwarzmann
Browse files

First rc/draft for receiving submissions

parent 032e24af
No related branches found
No related tags found
1 merge request!43Introduce docusaurus
......@@ -9,22 +9,35 @@ Das Token muss dann bei jeder Anfrage über den `Authentication`-Header mitgesch
Da ein Token **max. 24h** gültig ist, muss dieses rechtzeitig erneuert werden.
:::caution Generierung eines User-Tokens für sendende Systeme
Für sendende Systeme reicht der OAuth-Access-Token nicht aus um Zugriff auf die API zu bekommen.
Sendende System müssen für den Zugriff auf die API ein User-Token generieren, welches Sie zusammen mit dem Access-Token an die API übermiteln müssen.
Dieser Access-Token ist als mit dem privaten Schlüssel des API Clients zu signieren, der dem öffentlichen Schlüssel des API-Clients entspricht (Siehe [Accountregistrierung](../account)).
Für Aufbau und Beschreibung des User-Tokens siehe "[Generierung der JWT-Tokens](../details/authentication/users#generierung-der-jwt-tokens)"
:::
<Tabs
defaultValue="curl"
values={[
{ label: 'curl', value: 'curl', },
{ label: 'Java', value: 'java', },
{ label: 'Java (Spring)', value: 'java', },
{ label: 'C#', value: 'csharp', },
]
}>
<TabItem value="java">
```java
// TBD
```
</TabItem>
<TabItem value="csharp">
```csharp
// TBD
```
</TabItem>
<TabItem value="curl">
......@@ -42,10 +55,4 @@ Da ein Token **max. 24h** gültig ist, muss dieses rechtzeitig erneuert werden.
</TabItem>
</Tabs>
:::caution Generierung eines User-Tokens für sendende Systeme
Für sendende Systeme reicht der OAuth-Access-Token nicht aus um Zugriff auf die API zu bekommen.
Sendende System müssen für den Zugriff auf die API ein User-Token generieren, welches Sie zusammen mit dem Access-Token an die API übermiteln müssen.
Dieser Access-Token ist als mit dem privaten Schlüssel des API Clients zu signieren, der dem öffentlichen Schlüssel des API-Clients entspricht (Siehe [Accountregistrierung](../account)).
Für Aufbau und Beschreibung des User-Tokens siehe "[Generierung der JWT-Tokens](../details/authentication/users#generierung-der-jwt-tokens)"
:::
---
sidebar_position: 4
title: Entschlüsseln
title: 💬 Entschlüsseln
---
Um den Einreichung korrekt verarbeiten und überprüfen zu können müssen zuerst alle verschlüsselten Informationen entschlüsselt werden. Darunter fallen beispielsweise die Antragsmetadaten, die Fachdaten (falls vorhanden) oder Dokumente (falls vorhanden).
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
## Entschlüsseln von Daten im antragsempfangenden System (Java)
Um eine Einreichung korrekt verarbeiten und überprüfen zu können müssen zuerst alle verschlüsselten Informationen entschlüsselt werden.
Darunter fallen beispielsweise die Metadaten, die Fachdaten (falls vorhanden) oder Dokumente (falls vorhanden).
Wenn ein antragsempfangendes System (z.B. eine Fachanwendung oder virtuelle Poststelle) einen Einreichung erhält, kann es diesen mit Hilfe des privaten Schlüssels und der Java-Bibliothek `nimbus-jose-jwt` entschlüsseln.
## Entschlüsseln von Daten im antragsempfangenden Systeme
<Tabs
defaultValue="java"
values={[
{ label: 'Java (Spring)', value: 'java', },
{ label: 'C#', value: 'csharp', },
]
}>
<TabItem value="java">
Wenn ein empfangendes System (z.B. eine Fachanwendung oder virtuelle Poststelle) einen Einreichung erhält, kann es diese mit Hilfe des privaten Schlüssels und der Java-Bibliothek [`nimbus-jose-jwt`](https://connect2id.com/products/nimbus-jose-jwt) entschlüsseln.
```xml
<dependency>
......@@ -20,6 +33,7 @@ Wenn ein antragsempfangendes System (z.B. eine Fachanwendung oder virtuelle Post
Hierfür muss zuerst der private Schlüssel eingelesen werden. Bei `nimbus-jose-jwt` gibt es für RSA Schlüssel die Klasse RSAKey, um diese zu lesen:
```java
// ⤹ InputStream
String keyStr = new String(existingPrivateKey.readAllBytes());
RSAKey jwk = RSAKey.parse(keyStr);
```
......@@ -27,14 +41,23 @@ RSAKey jwk = RSAKey.parse(keyStr);
Nach dem Einlesen können die verschlüsselten Daten (repräsentiert als Base64URL-kodierter String) mit Hilfe des Schlüssels entschlüsselt werden. Auch hier wird wieder abhängig vom Schlüssel eine entsprechende Klasse für die Entschlüsselung verwendet.
```java
// ⤹ InputStream
String encryptedStr = new String(jweString.readAllBytes());
JWEObject jweObject = JWEObject.parse(encryptedStr);
jweObject.decrypt(new RSADecrypter(jwk));
```
Abschliessend kann die entschlüsselte Payload weiterverarbeitet oder, wie in diesem Fall, ausgegeben werden.
Abschliessend kann die entschlüsselte Payload weiterverarbeitet oder, wie in diesem Fall, einfach ausgegeben werden.
```java
System.out.println(jweObject.getPayload().toString());
```
\ No newline at end of file
```
</TabItem>
<TabItem value="csharp">
https://github.com/dvsekhvalnov/jose-jwt
</TabItem>
</Tabs>
---
sidebar_position: 2
title: Zustellpunkt
title: 💬 Zustellpunkt
---
Behörden können über das FIT-Connect-System Zustellpunkte für Anträge bereitstellen. In der Regel geben sie dabei an, für welches Gebiet sie welchen Einreichung aus dem Leistungskatalog entgegennehmen. Darauf erhalten sie eine Destination ID, welche eine Eindeutige Zustelladresse für diese Leistung repräsentiert. Diese Destination ID wird im Diensteverzeichnis zusammen mit der LeiKa-ID und den Gemeindekennungen gelistet und wird somit für Antragsversender auffindbar.
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
Beim Anlegen eines Zustellpunktes übermittelt die Behörde außerdem noch einen Verschlüsselungs- und einen Signatur-Key, Informationen ob und wie sie über einen neuen Einreichung benachrichtigt werden soll und Datenschemas, denen die Antragsdaten, die an sie übermittelt werden, entsprechen müssen.
Behörden können über das FIT-Connect-System Zustellpunkte für Anträge bereitstellen. In der Regel geben sie dabei an, für welches Gebiet sie welchen Einreichung aus dem Leistungskatalog entgegennehmen. Darauf erhalten sie eine Destination ID, welche eine Eindeutige Zustelladresse für diese Leistung repräsentiert. Diese Destination ID wird im Diensteverzeichnis zusammen mit der LeiKa-ID und den Gemeindekennungen gelistet und wird somit für Antragsversender auffindbar.
Nachdem ein Zustellpunkt angelegt wurde, können über diesen Anträge empfangen werden. Wenn ein Einreichung für die Destination-ID eingegangen ist, wird die Fachanwendung darüber über einen Webhook benachrichtig. Um den Einreichung abzurufen muss die Fachanwendung sich zuerst via OAuth2 authentifizieren und kann sich dann mithilfe des JWT gegenüber des Fachverfahrens autorisieren und den Einreichung abrufen.
Nachdem ein Zustellpunkt angelegt wurde, können über diesen Anträge empfangen werden. Wenn eine Einreichung für die Destination-ID eingegangen ist, wird die Fachanwendung darüber über einen Webhook benachrichtigt. Um die Einreichung abzurufen muss die Fachanwendung sich zuerst via OAuth2 authentifizieren und kann sich dann mithilfe des JWT gegenüber des Fachverfahrens autorisieren und den Einreichung abrufen.
Nach dem Abruf der Einreichung hat die Fachanwendung über die sogenannten Security Event Tokens die Möglichkeit Statusaktualisierungen zum empfangenen Einreichung an das FIT-Connect-System zu übermitteln. Dieses benachrichtigt dann den Antragssteller wiederum via Webhook, E-Mail oder Push-Notification über die Statusänderung. Außerdem hat sie die Möglichkeit eine verschlüsselte Antwort auf den Einreichung zu hinterlegen, die ebenfalls vom Antragssteller abgerufen werden kann.
## Zustellpunkt anlegen
Ein Zustellpunkt kann entweder programmatisch oder über das Self-Service-Portal angelegt werden.
<Tabs
defaultValue="curl"
values={[
{ label: 'curl', value: 'curl', },
{ label: 'Self-Service-Portal', value: 'ssp', },
]
}>
<TabItem value="curl">
Im Falle der programmatischen Variante muss eine HTTP POST Nachricht an den Endpunkt des Zustellpunktes gesendet werden, der alle notwendigen Informationen beinhaltet.
Ein exemplarischer Inhalt ist unten abgebildet.
```json title="myDestination.json"
{
"contactInformation": {
"legalName": "Batman Ltd.",
"address": "Batmansq. 31, 10000 Berlin, DE",
"phone": "+49111111111",
"email": "max.mustermann@musterstadt.de",
"unit": "Referat Gotham"
},
"schemas": [
{
"schemaURI": "urn:x-what:some-schema",
"mimeType": "application/xml"
}
],
"callback": "https://example.com/callback",
"encryptionKid": "my-key-id-0xfff",
"publicKeys": {
"keys": [
{
"kty": "RSA",
"kid": "my-key-id-0xfff",
"alg": "RSA-OAEP-256",
"key_ops": ["wrapKey"],
"x5c": [
"MIID2DCCAkmgAwIBAgIGAXo...w73tI1m1+QAU/6chTyAWvxvATklto2KV+i36lw=="
],
"e": "AQAB",
"n": "hwAvWxlwpz7sH...2f0u3Ktf1tzzeGTl4UVnUrE35eXF"
}
]
}
}
```
Wenn die JSON-Datei entsprechend befüllt ist und man ein gültiges JWT hat, über den Befehl unten den Zustellpunkt anlegen.
```bash
$ export SERVICE_URL=<URL>
$ export JWT_TOKEN=eyJhbGciOiJIUzI1NiJ9.eyJJc3N1Z...NL-MKFrDGvn9TvkA
$ curl \
-H "Authentication: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
--data "@./myDestination.json" \
-X POST $SERVICE_URL/destionations
> {
"destinationId": "7881dba9-4055-4854-8b6d-11ea5b7f3047",
"schemas": [
{
"schemaURI": "urn:x-what:some-schema",
"mimeType": "application/xml"
}
],
"encryptionKid": "my-key-id-0xfff",
"publicKeys": {
"keys": [
{
"kty": "RSA",
"kid": "my-key-id-0xfff",
"alg": "RSA-OAEP-256",
"key_ops": ["wrapKey"],
"x5c": [
"MIID2DCCAkmgAwIBAgIGAXo...w73tI1m1+QAU/6chTyAWvxvATklto2KV+i36lw=="
],
"e": "AQAB",
"n": "hwAvWxlwpz7sH...2f0u3Ktf1tzzeGTl4UVnUrE35eXF"
}
]
},
"contactInformation": {
"legalName": "Batman Ltd.",
"address": "Batmansq. 31, 10000 Berlin, DE",
"phone": "+49111111111",
"email": "max.mustermann@musterstadt.de",
"unit": "Referat Gotham"
},
"callback": "https://example.com/callback"
}
```
</TabItem>
<TabItem value="ssp">
:::caution
Das Self-Service-Portal befindet sich noch in der Konzeption und ist daher noch nicht dokumentiert.
:::
</TabItem>
</Tabs>
---
sidebar_position: 1
title: Überblick
---
\ No newline at end of file
title: 💬 Überblick
---
import Mermaid from '@site/src/components/Mermaid'
Für den Empfang von Einreichungen und die Verarbeitung dieser werden in diesem und den folgenden Abschnitten alle notwendigen Aktionen beschrieben, um schnell die ersten Schritte machen zu können.
Als Leitlinie dafür ist der unten dargestellte Prozessablauf heranzuziehen, dessen Schritte im Folgenden beschrieben werden.
<Mermaid>
sequenceDiagram
participant C as Client;
participant F as FIT Connect;
C->>F: Zustellpunkt anlegen;
alt Callback;
F->>C: Über neue Einreichung benachrichtigen;
C->>F: Einreichung abfragen;
else Polling;
loop;
C->>F: Neue Einreichungen abfragen;
end;
end;
C->>C: Anlagen herunterladen;
C->>C: Metadaten, Fachdaten & Anlagen entschlüsseln;
C->>F: Empfang & Validität der Einreichung bestätigen;
</Mermaid>
\ No newline at end of file
---
sidebar_position: 6
title: Weiterverarbeitung
title: 💬 Empfangsbestätigung
---
Nachdem nun der Einreichung vollständig heruntergeladen wurde und validiert wurde, sollte dieser entsprechend bestätigt werden. Dies muss über ein HTTP PUT, wie unten aufgezeigt, durchgeführt werden.
Der letzte Schritt zum Empfang einer Einreichung ist die Bestätigung des Empfangs und damit auch der Gültigkeit der Einreichung.
Mit Gültigkeit ist hier gemeint, dass alle Informationen erfolgreich heruntergeladen, entschlüsselt und im Falle der Metadaten validiert werden konnten.
Jede weitere Validierung kann durchgeführt werden, hängt jedoch nicht mehr mit dem Transport, sondern der fachlichen Gültigkeit zusammen.
Der Empfang wird nun über ein HTTP PUT bestätigt, sodass das sendende System benachrichtigt werden kann.
```text
curl -H 'X-AnwenderId: <Id>' -X PUT <URL>/applications/<UUID>
```
```text
curl -H 'X-AnwenderId: subscriber' -X PUT localhost:8080/applications/9d618546-0ff7-4e93-9f15-714e5dd1bf12
> {}
```bash
$ export SERVICE_URL=<URL>
$ export JWT_TOKEN=eyJhbGciOiJIUzI1NiJ9.eyJJc3N1Z...NL-MKFrDGvn9TvkA
$ export SUBMISSION_ID=9d618546-0ff7-4e93-9f15-714e5dd1bf12
$ curl \
-H "Authentication: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-X PUT $SERVICE_URL/submissions/$SUBMISSION_ID
```
---
sidebar_position: 3
title: Einreichung erhalten
title: 💬 Einreichung erhalten
---
Wenn ein neuer Einreichung bereitsteht, kann dieser über mehrere Befehle heruntergeladen werden. Mehrere dahingehend, da erst alle allgemeinen Informationen zum Einreichung heruntergeladen werden müssen und dann, falls notwendig alle mit ihm verbundenen Anhänge.
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
```text
curl -H 'X-AnwenderId: <Id>' -X GET <URL>/applications/<UUID>
Neue Einreichungen können über zwei Wege erhalten werden. Entweder können neue Einreichungen über Polling abgefragt werden oder der Zustellpunkt wird über einen Callback vom Zustelldienst benachrichtigt.
# Falls ein Einreichung noch entsprechend Anhänge besitzt, können diese über folgenden Befehl heruntergeladen werden:
curl -H 'X-AnwenderId: <Id>' -X GET <URL>/applications/<UUID>/attachments/<UUID>
## Polling
Über Polling, regelmäßiges Abfragen der Schnittstelle, können alle Einreichungen abgefragt werden, die zum Abholen bereitstehen.
```bash
$ export SERVICE_URL=<URL>
$ export JWT_TOKEN=eyJhbGciOiJIUzI1NiJ9.eyJJc3N1Z...NL-MKFrDGvn9TvkA
$ curl \
-H "Authentication: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-X GET $SERVICE_URL/submissions
> {
"submissions": [
...
]
}
```
```text
curl -H 'X-AnwenderId: subscriber' -X GET localhost:8080/applications/9d618546-0ff7-4e93-9f15-714e5dd1bf12
## Callback
Wenn eine neue Einreichung im Zustelldienst bereitsteht und eine Callback-URL im Zustellpunkt hinterlegt ist, kann der Zustelldienst den Zustellpunkt auch direkt informieren.
Dies wäre die präferierte Variante, da dadurch unnötige Anfrage vermieden werden können und die Kommunikation so auf ein notwendig Mindestmaß reduziert wäre.
Wenn der Zustellpunkt benachrichtigt wird, dann kann dieser über mehrere Befehle die Einreichung mit allen verbundenen Ressourcen herunterladen.
Mehrere Befehle dahingehend, da erst alle allgemeinen Informationen zur Einreichung heruntergeladen werden müssen und dann, falls notwendig alle mit ihr verbundenen Anlagen.
In den Ausschnitten unten wird zuerst gezeigt, wie die allgemeinen Informationen abgefragt werden. Abhängig von der Struktur `announcedContentStructure` können dann noch weitere Ressourcen geladen werden.
Der Marker `data` gibt an, ob in dem Feld `encryptedData` Inhalt sein sollte oder nicht. In `attachments` sind die Identifikatoren der Anlagen zu finden, die separat herunterzuladen sind, wie im zweiten Beispiel gezeigt ist.
```bash title="Abfrage der Einreichung inkl. Fachdaten und Metadaten"
$ export SERVICE_URL=<URL>
$ export JWT_TOKEN=eyJhbGciOiJIUzI1NiJ9.eyJJc3N1Z...NL-MKFrDGvn9TvkA
$ export SUBMISSION_ID=9d618546-0ff7-4e93-9f15-714e5dd1bf12
$ curl \
-H "Authentication: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-X GET $SERVICE_URL/submissions/$SUBMISSION_ID
> {
"destinationId": "7a2668ad-3081-407c-9358-7ce4b6144b02",
"applicationId": "9d618546-0ff7-4e93-9f15-714e5dd1bf12",
"submissionId": "9d618546-0ff7-4e93-9f15-714e5dd1bf12",
"attachments": [],
"currentStatus": "forwarded",
"encryptedMetadata": "eyJhbGciOiAiUlNBLU9BRVAiLCAiZW5jIjogIkExMjhDQkMtSFMyNTYifQ.SsLgP2bNKYDYGzHvLYY7rsVEBHSms6_jW-WfglHqD9giJhWwrOwqLZOaoOycsf_EBJCkHq9-vbxRb7WiNdy_C9J0_RnRRBGII6z_G4bVb18bkbJMeZMV6vpUut_iuRWoct_weg_VZ3iR2xMbl-yE8Hnc63pAGJcIwngfZ3sMX8rBeni_koxCc88LhioP8zRQxNkoNpvw-kTCz0xv6SU_zL8p79_-_2zilVyMt76Pc7WV46iI3EWIvP6SG04sguaTzrDXCLp6ykLGaXB7NRFJ5PJ9Lmh5yinAJzCdWQ-4XKKkNPorSiVmRiRSQ4z0S2eo2LtvqJhXCrghKpBNgbtnJQ.Awelp3ryBVpdFhRckQ-KKw.1MyZ-3nky1EFO4UgTB-9C2EHpYh1Z-ij0RbiuuMez70nIH7uqL9hlhskutO0oPjqdpmNc9glSmO9pheMH2DVag.Xccck85XZMvG-fAJ6oDnAw",
"encryptedMetadata": "eyJhbGciOiA...5XZMvG-fAJ6oDnAw",
"encryptedData": null,
"statusHistory": [
{
"sourceState": "queued",
"targetState": "forwarded",
"details": "Callback von Destination 7a2668ad-3081-407c-9358-7ce4b6144b02 ausgelöst.",
"timestamp": "2021-05-26T09:12:59.68968+02:00"
},
{
"sourceState": "incomplete",
"targetState": "queued",
"details": "Einreichung versendet durch sender",
"timestamp": "2021-05-26T09:12:58.728397+02:00"
}
],
"statusHistory": [...],
"announcedContentStructure": {
"data": false,
"attachments": []
"attachments": [
"122668ad-3081-497c-9358-7ce4b6144b02",
]
}
}
```
```bash title="Herunterladen einer Anlage"
$ export SERVICE_URL=<URL>
$ export JWT_TOKEN=eyJhbGciOiJIUzI1NiJ9.eyJJc3N1Z...NL-MKFrDGvn9TvkA
$ export SUBMISSION_ID=9d618546-0ff7-4e93-9f15-714e5dd1bf12
$ export ATTACHMENT_ID=122668ad-3081-497c-9358-7ce4b6144b02
$ curl \
-H "Authentication: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-X GET $SERVICE_URL/submissions/$SUBMISSION_ID/attachments/$ATTACHMENT_ID
> 6r4H2H_WIzCv8Pd-uetmcbK...iVBKF3ylHRUahmZ
```
/** @type {import('@docusaurus/types').DocusaurusConfig} */
const gitBranch = process.env.GIT_BRANCH
const gitBranch = process.env.GIT_BRANCH || 'main'
const baseUrl = gitBranch === 'main' ? '/' : `/${gitBranch}/`
......@@ -28,12 +28,12 @@ module.exports = {
src: '/images/logo-fitko.svg',
},
items: [
// {
// type: 'docsVersionDropdown',
// position: 'right',
// dropdownActiveClassDisabled: true,
// docsPluginId: 'default',
// },
{
type: 'docsVersionDropdown',
position: 'right',
dropdownActiveClassDisabled: true,
docsPluginId: 'default',
},
],
},
footer: {
......
......@@ -3,6 +3,7 @@ import mermaid from 'mermaid'
mermaid.initialize({
startOnLoad: true,
sequence: { showSequenceNumbers: true },
})
const Mermaid = ({ children }) => {
useEffect(() => {
......
......@@ -2,9 +2,8 @@ dl dt {
font-weight: bold;
}
.alert *,
.alert a {
.alert * .alert a {
color: var(--ifm-font-color-base);
fill: var(--ifm-font-color-base);
stroke: var(--ifm-font-color-base);
}
\ No newline at end of file
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment